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