root / ase / parallel.py @ 16
Historique | Voir | Annoter | Télécharger (2,43 ko)
1 |
import sys |
---|---|
2 |
import time |
3 |
import atexit |
4 |
|
5 |
|
6 |
def paropen(name, mode='r', buffering=0): |
7 |
"""MPI-safe version of open function.
|
8 |
|
9 |
In read mode, the file is opened on all nodes. In write and
|
10 |
append mode, the file is opened on the master only, and /dev/null
|
11 |
is opened on all other nodes.
|
12 |
"""
|
13 |
if rank > 0 and mode[0] != 'r': |
14 |
name = '/dev/null'
|
15 |
return open(name, mode, buffering) |
16 |
|
17 |
|
18 |
def parprint(*args, **kwargs): |
19 |
"""MPI save print - prints only from master.
|
20 |
|
21 |
Tries to adopt python 3 behaviour.
|
22 |
"""
|
23 |
if rank > 0: |
24 |
return
|
25 |
defaults = { 'end' : '\n', |
26 |
'file' : sys.stdout }
|
27 |
for key in defaults: |
28 |
if not key in kwargs: |
29 |
kwargs[key] = defaults[key] |
30 |
|
31 |
for arg in args[:-1]: |
32 |
print >> kwargs['file'], arg, |
33 |
if len(args): |
34 |
last = args[-1]
|
35 |
else:
|
36 |
last = ''
|
37 |
if kwargs['end'] == '\n': |
38 |
print last
|
39 |
else:
|
40 |
print last,
|
41 |
|
42 |
# Check for special MPI-enabled Python interpreters:
|
43 |
if '_gpaw' in sys.modules: |
44 |
# http://wiki.fysik.dtu.dk/gpaw
|
45 |
from gpaw.mpi import world |
46 |
rank = world.rank |
47 |
size = world.size |
48 |
barrier = world.barrier |
49 |
elif 'asapparallel3' in sys.modules: |
50 |
# http://wiki.fysik.dtu.dk/Asap
|
51 |
# We cannot import asap3.mpi here, as that creates an import deadlock
|
52 |
#from asap3.mpi import world
|
53 |
import asapparallel3 |
54 |
world = asapparallel3.Communicator() |
55 |
rank = world.rank |
56 |
size = world.size |
57 |
barrier = world.barrier |
58 |
elif 'Scientific_mpi' in sys.modules: |
59 |
#
|
60 |
from Scientific.MPI import world |
61 |
rank = world.rank |
62 |
size = world.size |
63 |
barrier = world.barrier |
64 |
else:
|
65 |
# This is a standard Python interpreter:
|
66 |
rank = 0
|
67 |
size = 1
|
68 |
world = None
|
69 |
def barrier(): |
70 |
pass
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
def register_parallel_cleanup_function(): |
76 |
"""Call MPI_Abort if python crashes.
|
77 |
|
78 |
This will terminate the processes on the other nodes."""
|
79 |
|
80 |
if size == 1: |
81 |
return
|
82 |
|
83 |
def cleanup(sys=sys, time=time, world=world): |
84 |
error = getattr(sys, 'last_type', None) |
85 |
if error:
|
86 |
sys.stdout.flush() |
87 |
sys.stderr.write(('ASE CLEANUP (node %d): %s occurred. ' +
|
88 |
'Calling MPI_Abort!\n') % (world.rank, error))
|
89 |
sys.stderr.flush() |
90 |
# Give other nodes a moment to crash by themselves (perhaps
|
91 |
# producing helpful error messages):
|
92 |
time.sleep(3)
|
93 |
world.abort(42)
|
94 |
|
95 |
atexit.register(cleanup) |