Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

r""" 

Parallelization control 

 

This module defines the singleton class :class:`Parallelism` to govern the 

parallelization of computations in some specific topics. It allows the user to 

set the number of processes to be used for parallelization. 

 

Some examples of use are provided in the documentation of 

:meth:`sage.tensor.modules.comp.Components.contract`. 

 

AUTHORS: 

 

- Marco Mancini, Eric Gourgoulhon, Michal Bejger (2015): initial version 

 

""" 

 

#****************************************************************************** 

# Copyright (C) 2015 Marco Mancini <marco.mancini@obspm.fr> 

# 

# Distributed under the terms of the GNU General Public License (GPL) 

# as published by the Free Software Foundation; either version 2 of 

# the License, or (at your option) any later version. 

# http://www.gnu.org/licenses/ 

#****************************************************************************** 

from __future__ import absolute_import 

 

from sage.structure.sage_object import SageObject 

from sage.misc.fast_methods import Singleton 

from sage.parallel.ncpus import ncpus 

from sage.rings.integer import Integer 

 

class Parallelism(Singleton, SageObject): 

r""" 

Singleton class for managing the number of processes used in parallel 

computations involved in various fields. 

 

EXAMPLES: 

 

The number of processes is initialized to 1 (no parallelization) for 

each field (only tensor computations are implemented at the moment):: 

 

sage: Parallelism() 

Number of processes for parallelization: 

- tensor computations: 1 

 

Using 4 processes to parallelize tensor computations:: 

 

sage: Parallelism().set('tensor', nproc=4) 

sage: Parallelism() 

Number of processes for parallelization: 

- tensor computations: 4 

sage: Parallelism().get('tensor') 

4 

 

Using 6 processes to parallelize all types of computations:: 

 

sage: Parallelism().set(nproc=6) 

sage: Parallelism() 

Number of processes for parallelization: 

- tensor computations: 6 

 

Using all the cores available on the computer to parallelize tensor 

computations:: 

 

sage: Parallelism().set('tensor') 

sage: Parallelism() # random (depends on the computer) 

Number of processes for parallelization: 

- tensor computations: 8 

 

Using all the cores available on the computer to parallelize all types 

of computations:: 

 

sage: Parallelism().set() 

sage: Parallelism() # random (depends on the computer) 

Number of processes for parallelization: 

- tensor computations: 8 

 

Switching off all parallelizations:: 

 

sage: Parallelism().set(nproc=1) 

 

""" 

def __init__(self): 

r""" 

Construct the single instance of class Parallelism (singleton model). 

 

TESTS:: 

 

sage: par = Parallelism() 

sage: par 

Number of processes for parallelization: 

- tensor computations: 1 

 

Test of the singleton character:: 

 

sage: Parallelism() is par 

True 

 

The test suite is passed:: 

 

sage: TestSuite(par).run() 

 

""" 

self._default = ncpus() # default number of proc. used in parallelizations 

self._nproc = {'tensor' : 1} # dict. of number of processes to be used 

# (keys: computational field) 

 

def _repr_(self): 

r""" 

String representation of the object. 

 

TESTS:: 

 

sage: Parallelism()._repr_() 

'Number of processes for parallelization:\n - tensor computations: 1' 

 

""" 

resu = "Number of processes for parallelization:\n" 

for field in sorted(self._nproc): 

resu += " - {} computations: {}\n".format(field, self._nproc[field]) 

return resu[:-1] 

 

def reset(self): 

r""" 

Put the singleton object ``Parallelism()`` in the same state as 

immediately after its creation. 

 

EXAMPLES: 

 

State of ``Parallelism()`` just after its creation:: 

 

sage: Parallelism() 

Number of processes for parallelization: 

- tensor computations: 1 

sage: Parallelism().get_default() # random (depends on the computer) 

8 

 

Changing some values:: 

 

sage: Parallelism().set_default(6) 

sage: Parallelism().set() 

sage: Parallelism() 

Number of processes for parallelization: 

- tensor computations: 6 

sage: Parallelism().get_default() 

6 

 

Back to the initial state:: 

 

sage: Parallelism().reset() 

sage: Parallelism() 

Number of processes for parallelization: 

- tensor computations: 1 

sage: Parallelism().get_default() # random (depends on the computer) 

8 

 

""" 

self._default = ncpus() 

for field in self._nproc: 

self._nproc[field] = 1 

 

def set(self, field=None, nproc=None): 

r""" 

Set the number of processes to be launched for parallel computations 

regarding some specific field. 

 

INPUT: 

 

- ``field`` -- (default: ``None``) string specifying the computational 

field for which the number of parallel processes is to be set; if 

``None``, all fields are considered 

- ``nproc`` -- (default: ``None``) number of processes to be used for 

parallelization; if ``None``, the number of processes will be set to 

the default value, which, unless redefined by :meth:`set_default`, 

is the total number of cores found on the computer. 

 

EXAMPLES: 

 

The default is a single processor (no parallelization):: 

 

sage: Parallelism() 

Number of processes for parallelization: 

- tensor computations: 1 

 

Asking for parallelization on 4 cores in tensor algebra:: 

 

sage: Parallelism().set('tensor', nproc=4) 

sage: Parallelism() 

Number of processes for parallelization: 

- tensor computations: 4 

 

Using all the cores available on the computer:: 

 

sage: Parallelism().set('tensor') 

sage: Parallelism() # random (depends on the computer) 

Number of processes for parallelization: 

- tensor computations: 8 

 

Using 6 cores in all parallelizations:: 

 

sage: Parallelism().set(nproc=6) 

sage: Parallelism() 

Number of processes for parallelization: 

- tensor computations: 6 

 

Using all the cores available on the computer in all parallelizations:: 

 

sage: Parallelism().set() 

sage: Parallelism() # random (depends on the computer) 

Number of processes for parallelization: 

- tensor computations: 8 

 

Switching off the parallelization:: 

 

sage: Parallelism().set(nproc=1) 

sage: Parallelism() 

Number of processes for parallelization: 

- tensor computations: 1 

 

""" 

if field is None: 

for fi in self._nproc: 

self.set(field=fi, nproc=nproc) 

else: 

if field not in self._nproc : 

raise KeyError("entry for field {} is not ".format(field) + 

"implemented in Parallelism") 

if nproc is None: 

self._nproc[field] = self._default 

else: 

if not isinstance(nproc, (int,Integer)): 

raise TypeError("nproc must be integer") 

self._nproc[field] = nproc 

 

def get(self, field): 

r""" 

Return the number of processes which will be used in parallel 

computations regarding some specific field. 

 

INPUT: 

 

- ``field`` -- string specifying the part of Sage involved in 

parallel computations 

 

OUTPUT: 

 

- number of processes used in parallelization of computations 

pertaining to ``field`` 

 

EXAMPLES: 

 

The default is a single process (no parallelization):: 

 

sage: Parallelism().reset() 

sage: Parallelism().get('tensor') 

1 

 

Asking for parallelization on 4 cores:: 

 

sage: Parallelism().set('tensor', nproc=4) 

sage: Parallelism().get('tensor') 

4 

 

""" 

if field not in self._nproc: 

raise KeyError("entry for field {} is not ".format(field) + 

"implemented in Parallelism()") 

return self._nproc[field] 

 

 

def get_all(self): 

r""" 

Return the number of processes which will be used in parallel 

computations in all fields 

 

OUTPUT: 

 

- dictionary of the number of processes, with the computational fields 

as keys 

 

EXAMPLES:: 

 

sage: Parallelism().reset() 

sage: Parallelism().get_all() 

{'tensor': 1} 

 

Asking for parallelization on 4 cores:: 

 

sage: Parallelism().set(nproc=4) 

sage: Parallelism().get_all() 

{'tensor': 4} 

 

""" 

return self._nproc 

 

 

def set_default(self, nproc=None): 

r""" 

Set the default number of processes to be launched in parallel 

computations. 

 

INPUT: 

 

- ``nproc`` -- (default: ``None``) default number of processes; 

if ``None``, the number of processes will be set to the total number 

of cores found on the computer. 

 

EXAMPLES: 

 

A priori the default number of process for parallelization is the 

total number of cores found on the computer:: 

 

sage: Parallelism().get_default() # random (depends on the computer) 

8 

 

Changing it thanks to ``set_default``:: 

 

sage: Parallelism().set_default(nproc=4) 

sage: Parallelism().get_default() 

4 

 

Setting it back to the total number of cores available on the computer:: 

 

sage: Parallelism().set_default() 

sage: Parallelism().get_default() # random (depends on the computer) 

8 

 

""" 

if nproc is None: 

self._default = ncpus() 

else: 

if not isinstance(nproc,(int,Integer)): 

raise TypeError("nproc must be integer") 

self._default = nproc 

 

def get_default(self): 

r""" 

Return the default number of processes to be launched in parallel 

computations. 

 

EXAMPLES: 

 

A priori, the default number of process for parallelization is the 

total number of cores found on the computer:: 

 

sage: Parallelism().reset() 

sage: Parallelism().get_default() # random (depends on the computer) 

8 

 

It can be changed via :meth:`set_default`:: 

 

sage: Parallelism().set_default(nproc=4) 

sage: Parallelism().get_default() 

4 

 

""" 

return self._default