Author: bugman
Date: Thu Mar 22 10:13:53 2012
New Revision: 15600
URL: http://svn.gna.org/viewcvs/relax?rev=15600&view=rev
Log:
Redesigned how the multi-processor package terminates program execution.
The Processor.exit() method has been introduced to perform this action. By
default (used by the
uni-processor fabric), the method does nothing. The mpi4py_processor.py module
functions exit() and
exit_mpi() have been merged into the Mpi4py_processor.exit() method.
Modified:
1.3/multi/mpi4py_processor.py
1.3/multi/processor.py
1.3/multi/uni_processor.py
Modified: 1.3/multi/mpi4py_processor.py
URL:
http://svn.gna.org/viewcvs/relax/1.3/multi/mpi4py_processor.py?rev=15600&r1=15599&r2=15600&view=diff
==============================================================================
--- 1.3/multi/mpi4py_processor.py (original)
+++ 1.3/multi/mpi4py_processor.py Thu Mar 22 10:13:53 2012
@@ -42,11 +42,6 @@
from multi.multi_processor_base import Multi_processor,
Too_few_slaves_exception
-# save original sys.exit to call after wrapper
-_sys_exit = sys.exit
-
-in_main_loop = False
-
def broadcast_command(command):
for i in range(1, MPI.COMM_WORLD.size):
@@ -63,38 +58,6 @@
break
-def exit(status=None):
- """Wrapper for the sys.exit function."""
-
- # CHECKME is status ok
-
- # Execution on the slave.
- if MPI.COMM_WORLD.rank != 0:
- if in_main_loop:
- raise Exception('sys.exit unexpectedley called on slave!')
- else:
- sys.stderr.write('\n')
-
sys.stderr.write('***********************************************\n')
- sys.stderr.write('\n')
- sys.stderr.write('warning sys.exit called before mpi4py main
loop\n')
- sys.stderr.write('\n')
-
sys.stderr.write('***********************************************\n')
- sys.stderr.write('\n')
- MPI.COMM_WORLD.Abort()
-
- # Execution on the master.
- else:
- exit_mpi()
- _sys_exit(status)
-
-
-def exit_mpi():
- if MPI.Is_initialized() and not MPI.Is_finalized() and MPI.COMM_WORLD.rank
== 0:
- broadcast_command(Exit_command())
- ditch_all_results()
-
-
-
class Mpi4py_processor(Multi_processor):
"""The mpi4py multi-processor class."""
@@ -116,8 +79,8 @@
super(Mpi4py_processor,
self).__init__(processor_size=mpi_processor_size, callback=callback)
- # wrap sys.exit to close down mpi before exiting
- sys.exit = exit
+ # Initialise a flag for determining if we are in the run() method or
not.
+ self.in_main_loop = False
def abort(self):
@@ -148,6 +111,44 @@
MPI.COMM_WORLD.send([name, value], dest=i, tag=10)
+ def exit(self, status=0):
+ """Exit the mpi4py processor with the given status.
+
+ @keyword status: The program exit status.
+ @type status: int
+ """
+
+ # Execution on the slave.
+ if MPI.COMM_WORLD.rank != 0:
+ # Catch sys.exit being called on an executing slave.
+ if self.in_main_loop:
+ raise Exception('sys.exit unexpectedly called on slave!')
+
+ # Catch sys.exit
+ else:
+ sys.stderr.write('\n')
+
sys.stderr.write('***********************************************\n')
+ sys.stderr.write('\n')
+ sys.stderr.write('warning sys.exit called before mpi4py main
loop\n')
+ sys.stderr.write('\n')
+
sys.stderr.write('***********************************************\n')
+ sys.stderr.write('\n')
+ MPI.COMM_WORLD.Abort()
+
+ # Execution on the master.
+ else:
+ # Slave clean up.
+ if MPI.Is_initialized() and not MPI.Is_finalized() and
MPI.COMM_WORLD.rank == 0:
+ # Send the exit command to all slaves.
+ broadcast_command(Exit_command())
+
+ # Dump all results.
+ ditch_all_results()
+
+ # Exit the program with the given status.
+ sys.exit(status)
+
+
def get_intro_string(self):
"""Return the string to append to the end of the relax introduction
string.
@@ -190,10 +191,9 @@
def run(self):
- global in_main_loop
- in_main_loop = True
+ self.in_main_loop = True
super(Mpi4py_processor, self).run()
- in_main_loop = False
+ self.in_main_loop = False
def slave_receive_commands(self):
Modified: 1.3/multi/processor.py
URL:
http://svn.gna.org/viewcvs/relax/1.3/multi/processor.py?rev=15600&r1=15599&r2=15600&view=diff
==============================================================================
--- 1.3/multi/processor.py (original)
+++ 1.3/multi/processor.py Thu Mar 22 10:13:53 2012
@@ -180,22 +180,18 @@
def abort(self):
"""Shutdown the multi processor in exceptional conditions - designed
for overriding.
- This method is called after an exception from the master or slave has
been raised and
- processed and is responsible for the shutdown of the multi processor
fabric and terminating
- the application. The functions should be called as the last thing that
- Application_callback.handle_exception does.
-
- As an example of the methods use see Mpi4py_processor.abort which calls
- MPI.COMM_WORLD.Abort() to cleanly shutdown the mpi framework and
remove dangling processes.
-
- The default action is to call sys.exit()
+ This method is called after an exception from the master or slave has
been raised and processed and is responsible for the shutdown of the multi
processor fabric and terminating the application. The functions should be
called as the last thing that Application_callback.handle_exception does.
+
+ As an example of the methods use see Mpi4py_processor.abort which
calls MPI.COMM_WORLD.Abort() to cleanly shutdown the mpi framework and remove
dangling processes.
+
+ The default action is to call the special self.exit() method.
@see: multi.processor.Application_callback.
@see: multi.mpi4py_processor.Mpi4py_processor.abort().
@see: mpi4py.MPI.COMM_WORLD.Abort().
"""
- sys.exit()
+ self.exit()
def add_to_queue(self, command, memo=None):
@@ -216,9 +212,14 @@
raise_unimplemented(self.add_to_queue)
- # FIXME is this used?
-# def exit(self):
-# raise_unimplemented(self.exit)
+ def exit(self, status=0):
+ """Exit the processor with the given status.
+
+ This default method allows the program to drop off the end and
terminate as it normally would - i.e. this method does nothing.
+
+ @keyword status: The program exit status.
+ @type status: int
+ """
def data_upload(self, name=None, value=None, rank=None):
@@ -489,10 +490,9 @@
# Execute any tear down code needed for the specific processor fabrics.
self.post_run()
- # End of execution on the master, so kill the slaves.
+ # End of execution, so perform any exiting actions needed by the
specific processor fabrics.
if self.on_master():
- # note this a modified exit that kills all MPI processors
- sys.exit()
+ self.exit()
def run_command_globally(self, command):
Modified: 1.3/multi/uni_processor.py
URL:
http://svn.gna.org/viewcvs/relax/1.3/multi/uni_processor.py?rev=15600&r1=15599&r2=15600&view=diff
==============================================================================
--- 1.3/multi/uni_processor.py (original)
+++ 1.3/multi/uni_processor.py Thu Mar 22 10:13:53 2012
@@ -59,10 +59,6 @@
if memo != None:
command.set_memo_id(memo)
self.memo_map[memo.memo_id()] = memo
-
-
- def exit(self):
- sys.exit()
def get_intro_string(self):
_______________________________________________
relax (http://nmr-relax.com)
This is the relax-commits mailing list
[email protected]
To unsubscribe from this list, get a password
reminder, or change your subscription options,
visit the list information page at
https://mail.gna.org/listinfo/relax-commits