Author: bugman Date: Thu Mar 1 13:36:46 2012 New Revision: 15419 URL: http://svn.gna.org/viewcvs/relax?rev=15419&view=rev Log: Created a special Verbosity singleton for controlling the multi-processor package print outs. This controls the text prepended to the output from the slaves, as well as all print outs from the master processor. If the verbosity level is set to 0, then nothing but warnings and errors are printed. The level of 1 prepends text to the slave IO streams and the print out of from the master of the active slave set. This will be important for very fine grained parallelisation whereby the multi-processor is used at the level of the basic function call or lower. Modified: 1.3/multi/__init__.py 1.3/multi/misc.py 1.3/multi/multi_processor_base.py 1.3/multi/processor.py 1.3/relax.py Modified: 1.3/multi/__init__.py URL: http://svn.gna.org/viewcvs/relax/1.3/multi/__init__.py?rev=15419&r1=15418&r2=15419&view=diff ============================================================================== --- 1.3/multi/__init__.py (original) +++ 1.3/multi/__init__.py Thu Mar 1 13:36:46 2012 @@ -40,25 +40,27 @@ from api import Result_command, Slave_command from memo import Memo from misc import import_module as _import_module +from misc import Verbosity as _Verbosity; _verbosity = _Verbosity() #FIXME error checking for if module required not found. #FIXME module loading code needs to be in a util module. #FIXME: remove parameters that are not required to load the module (processor_size). -def load_multiprocessor(processor_name, callback, processor_size): +def load_multiprocessor(processor_name, callback, processor_size, verbosity=1): """Load a multi processor given its name. Dynamically load a multi processor, the current algorithm is to search in module multi for a module called <processor_name>.<Processor_name> (note capitalisation). - @todo: This algorithm needs to be improved to allow users to load processors without altering - the relax source code. + @todo: This algorithm needs to be improved to allow users to load processors without altering the relax source code. @todo: Remove non-essential parameters. @param processor_name: Name of the processor module/class to load. @type processor_name: str + @keyword verbosity: The verbosity level at initialisation. This can be changed during program execution. A value of 0 suppresses all output. A value of 1 causes the basic multi-processor information to be printed. A value of 2 will switch on a number of debugging print outs. Values greater than 2 currently do nothing, though this might change in the future. + @type keyword: int @return: A loaded processor object or None to indicate failure. @rtype: multi.processor.Processor instance """ @@ -67,6 +69,9 @@ if processor_name not in ['uni', 'mpi4py']: _sys.stderr.write("The processor type '%s' is not supported.\n" % processor_name) _sys.exit() + + # Store the verbosity level. + _verbosity.set(verbosity) # The Processor details. processor_name = processor_name + '_processor' Modified: 1.3/multi/misc.py URL: http://svn.gna.org/viewcvs/relax/1.3/multi/misc.py?rev=15419&r1=15418&r2=15419&view=diff ============================================================================== --- 1.3/multi/misc.py (original) +++ 1.3/multi/misc.py Thu Mar 1 13:36:46 2012 @@ -28,14 +28,12 @@ """ -def import_module(module_path, verbose=False): +def import_module(module_path): """Import the python module named by module_path. @param module_path: A module path in python dot separated format. Note: this currently doesn't support relative module paths as defined by pep328 and python 2.5. @type module_path: str - @keyword verbose: Whether to report successes and failures for debugging. - @type verbose: bool @return: The module path as a list of module instances or None if the module path cannot be found in the python path. @rtype: list of class module instances or None @@ -45,7 +43,10 @@ # Import the module. module = __import__(module_path, globals(), locals(), []) - if verbose: + + # Debugging. + verbosity = Verbosity() + if verbosity.level() > 2: print('loaded module %s' % module_path) #FIXME: needs more failure checking @@ -141,3 +142,48 @@ message = textwrap.dedent(message) result = message % ('-'*120, ''.join(self.traceback), self.rank, self.name, self.exception_name, self.exception_string, '-'*120) return result + + + +class Verbosity(object): + """A special singleton structure for changing the verbosity level on the fly.""" + + # Class variable for storing the class instance. + instance = None + + def __new__(self, *args, **kargs): + """Replacement function for implementing the singleton design pattern.""" + + # First initialisation. + if self.instance is None: + # Create a new object. + self.instance = object.__new__(self, *args, **kargs) + + # Set the initial verbosity level to nothing. + self._value = 0 + + # Already initialised, so return the instance. + return self.instance + + + def level(self): + """Return the current verbosity level. + + @return: The current verbosity level. + @rtype: int + """ + + # Return the level. + return self._value + + + def set(self, value=0): + """Set the verbosity level. + + @keyword value: If given, then the verbosity level will be set. A value of 0 suppresses all output. A value of 1 causes the minimal amount of information to be printed. A value of 2 will switch on a number of debugging print outs. Values greater than 2 currently do nothing, though this might change in the future. + @type value: int + """ + + # Set the value if given. + if value != None: + self._value = value Modified: 1.3/multi/multi_processor_base.py URL: http://svn.gna.org/viewcvs/relax/1.3/multi/multi_processor_base.py?rev=15419&r1=15418&r2=15419&view=diff ============================================================================== --- 1.3/multi/multi_processor_base.py (original) +++ 1.3/multi/multi_processor_base.py Thu Mar 1 13:36:46 2012 @@ -42,8 +42,8 @@ import traceback # relax module imports. -from multi.api import Batched_result_command, Capturing_exception, Result, Result_command, Result_string, Result_exception -from multi.misc import raise_unimplemented +from multi.api import Batched_result_command, Result, Result_command, Result_string, Result_exception +from multi.misc import Capturing_exception, raise_unimplemented, Verbosity; verbosity = Verbosity() from multi.processor import Processor @@ -269,9 +269,10 @@ # Get the result. result = self.master_recieve_result() - # Print out. - print('\nIdle set: %s' % idle_set) - print('Running set: %s' % running_set) + # Debugging print out. + if verbosity.level(): + print('\nIdle set: %s' % idle_set) + print('Running set: %s' % running_set) # Shift the processor rank to the idle set. if result.completed: Modified: 1.3/multi/processor.py URL: http://svn.gna.org/viewcvs/relax/1.3/multi/processor.py?rev=15419&r1=15418&r2=15419&view=diff ============================================================================== --- 1.3/multi/processor.py (original) +++ 1.3/multi/processor.py Thu Mar 1 13:36:46 2012 @@ -103,7 +103,7 @@ # relax module imports. from multi.api import Null_result_command -from multi.misc import raise_unimplemented +from multi.misc import raise_unimplemented, Verbosity; verbosity = Verbosity() from multi.processor_io import Redirect_text @@ -257,6 +257,10 @@ @rtype: list of 2 str """ + # Only prepend test if the verbosity level is set. + if not verbosity.level(): + return '', '' + # Initialise. pre_string = '' stdout_string = '' @@ -311,7 +315,10 @@ if self.rank() == 0: end_time = time.time() time_delta_str = self.get_time_delta(self.start_time, end_time) - print('\nOverall runtime: ' + time_delta_str + '\n') + + # Print out of the total run time. + if verbosity.level(): + print('\nOverall runtime: ' + time_delta_str + '\n') def pre_run(self): Modified: 1.3/relax.py URL: http://svn.gna.org/viewcvs/relax/1.3/relax.py?rev=15419&r1=15418&r2=15419&view=diff ============================================================================== --- 1.3/relax.py (original) +++ 1.3/relax.py Thu Mar 1 13:36:46 2012 @@ -88,7 +88,7 @@ # Set up the multi-processor elements. callbacks = Application_callback(master=relax) - processor = load_multiprocessor(relax.multiprocessor_type, callbacks, processor_size=relax.n_processors) + processor = load_multiprocessor(relax.multiprocessor_type, callbacks, processor_size=relax.n_processors, verbosity=0) # Place the processor fabric intro string into the info box. info = Info_box()