Author: bugman Date: Wed Feb 29 13:37:57 2012 New Revision: 15406 URL: http://svn.gna.org/viewcvs/relax?rev=15406&view=rev Log: Shifted the main interface of the multi-processor package into the __init__ module. The two main interfaces, or the API with the calling program, are the load_multiprocessor() function and the Processor_box class. These have been shifted from the multi.processor module as this is mainly a base class. The import_module() function has also been shifted into __init__ and been made a private function, removing it from the API. Modified: 1.3/generic_fns/minimise.py 1.3/multi/__init__.py 1.3/multi/processor.py 1.3/relax.py 1.3/specific_fns/model_free/mf_minimise.py Modified: 1.3/generic_fns/minimise.py URL: http://svn.gna.org/viewcvs/relax/1.3/generic_fns/minimise.py?rev=15406&r1=15405&r2=15406&view=diff ============================================================================== --- 1.3/generic_fns/minimise.py (original) +++ 1.3/generic_fns/minimise.py Wed Feb 29 13:37:57 2012 @@ -29,7 +29,7 @@ # relax module imports. from generic_fns.mol_res_spin import return_spin, spin_loop from generic_fns import pipes -from multi.processor import Processor_box +from multi import Processor_box from relax_errors import RelaxError import specific_fns from status import Status; status = Status() Modified: 1.3/multi/__init__.py URL: http://svn.gna.org/viewcvs/relax/1.3/multi/__init__.py?rev=15406&r1=15405&r2=15406&view=diff ============================================================================== --- 1.3/multi/__init__.py (original) +++ 1.3/multi/__init__.py Wed Feb 29 13:37:57 2012 @@ -31,3 +31,107 @@ __doc__ = \ """Package for multi-processor code execution.""" + + +def _import_module(module_path, verbose=False): + '''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 + ''' + + result = None + + # Import the module. + module = __import__(module_path, globals(), locals(), []) + if verbose: + print('loaded module %s' % module_path) + + #FIXME: needs more failure checking + if module != None: + result = [module] + components = module_path.split('.') + for component in components[1:]: + module = getattr(module, component) + result.append(module) + return result + + +#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): + '''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: Remove non-essential parameters. + + @param processor_name: Name of the processor module/class to load. + @type processor_name: str + @return: A loaded processor object or None to indicate failure. + @rtype: multi.processor.Processor instance + ''' + + # Check that the processor type is supported. + if processor_name not in ['uni', 'mpi4py']: + raise RelaxError("The processor type '%s' is not supported." % processor_name) + + # The Processor details. + processor_name = processor_name + '_processor' + class_name = processor_name[0].upper() + processor_name[1:] + module_path = '.'.join(('multi', processor_name)) + + # Load the module containing the specific processor. + modules = _import_module(module_path) + + # Access the class from within the module. + if hasattr(modules[-1], class_name): + clazz = getattr(modules[-1], class_name) + else: + raise Exception("can't load class %s from module %s" % (class_name, module_path)) + + # Instantiate the Processor. + object = clazz(callback=callback, processor_size=processor_size) + + # Load the Processor_box container and store the details and Processor instance. + processor_box = Processor_box() + processor_box.processor = object + processor_box.processor_name = processor_name + processor_box.class_name = class_name + + # Return the Processor instance. + return object + + + +class Processor_box(object): + """A storage class for the Processor instance and its attributes. + + This singleton contains Processor instances and information about these Processors. Importantly + this container gives the calling code access to the Processor. + """ + + # 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: + self.instance = object.__new__(self, *args, **kargs) + + # Already initialised, so return the instance. + return self.instance Modified: 1.3/multi/processor.py URL: http://svn.gna.org/viewcvs/relax/1.3/multi/processor.py?rev=15406&r1=15405&r2=15406&view=diff ============================================================================== --- 1.3/multi/processor.py (original) +++ 1.3/multi/processor.py Wed Feb 29 13:37:57 2012 @@ -107,88 +107,6 @@ from relax_errors import RelaxError -def import_module(module_path, verbose=False): - '''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 - ''' - - result = None - - # Import the module. - module = __import__(module_path, globals(), locals(), []) - if verbose: - print('loaded module %s' % module_path) - - #FIXME: needs more failure checking - if module != None: - result = [module] - components = module_path.split('.') - for component in components[1:]: - module = getattr(module, component) - result.append(module) - return result - - -#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): - '''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: Remove non-essential parameters. - - @param processor_name: Name of the processor module/class to load. - @type processor_name: str - @return: A loaded processor object or None to indicate failure. - @rtype: multi.processor.Processor instance - ''' - - # Check that the processor type is supported. - if processor_name not in ['uni', 'mpi4py']: - raise RelaxError("The processor type '%s' is not supported." % processor_name) - - # The Processor details. - processor_name = processor_name + '_processor' - class_name = processor_name[0].upper() + processor_name[1:] - module_path = '.'.join(('multi', processor_name)) - - # Load the module containing the specific processor. - modules = import_module(module_path) - - # Access the class from within the module. - if hasattr(modules[-1], class_name): - clazz = getattr(modules[-1], class_name) - else: - raise Exception("can't load class %s from module %s" % (class_name, module_path)) - - # Instantiate the Processor. - object = clazz(callback=callback, processor_size=processor_size) - - # Load the Processor_box container and store the details and Processor instance. - processor_box = Processor_box() - processor_box.processor = object - processor_box.processor_name = processor_name - processor_box.class_name = class_name - - # Return the Processor instance. - return object - - def raise_unimplemented(method): '''Standard function for raising NotImplementedError for unimplemented abstract methods. @@ -703,28 +621,6 @@ -class Processor_box(object): - """A storage class for the Processor instance and its attributes. - - This singleton contains Processor instances and information about these Processors. Importantly - this container gives the calling code access to the Processor. - """ - - # 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: - self.instance = object.__new__(self, *args, **kargs) - - # Already initialised, so return the instance. - return self.instance - - - class Result(object): '''A basic result object returned from a slave processor via return_object. Modified: 1.3/relax.py URL: http://svn.gna.org/viewcvs/relax/1.3/relax.py?rev=15406&r1=15405&r2=15406&view=diff ============================================================================== --- 1.3/relax.py (original) +++ 1.3/relax.py Wed Feb 29 13:37:57 2012 @@ -54,7 +54,8 @@ import generic_fns if dep_check.wx_module: import gui -from multi.processor import Application_callback, Processor +from multi import load_multiprocessor +from multi.processor import Application_callback from prompt.gpl import gpl from prompt import interpreter import relax_errors @@ -88,7 +89,7 @@ # Set up the multi-processor elements. callbacks = Application_callback(master=relax) - processor = Processor.load_multiprocessor(relax.multiprocessor_type, callbacks, processor_size=relax.n_processors) + processor = load_multiprocessor(relax.multiprocessor_type, callbacks, processor_size=relax.n_processors) # Place the processor fabric intro string into the info box. info = Info_box() Modified: 1.3/specific_fns/model_free/mf_minimise.py URL: http://svn.gna.org/viewcvs/relax/1.3/specific_fns/model_free/mf_minimise.py?rev=15406&r1=15405&r2=15406&view=diff ============================================================================== --- 1.3/specific_fns/model_free/mf_minimise.py (original) +++ 1.3/specific_fns/model_free/mf_minimise.py Wed Feb 29 13:37:57 2012 @@ -36,7 +36,7 @@ from generic_fns.diffusion_tensor import diff_data_exists from generic_fns.mol_res_spin import count_spins, exists_mol_res_spin_data, return_spin_from_index, spin_loop from maths_fns.mf import Mf -from multi.processor import Processor_box +from multi import Processor_box from multi_processor_commands import MF_grid_command, MF_memo, MF_minimise_command from physical_constants import h_bar, mu0, return_gyromagnetic_ratio from relax_errors import RelaxError, RelaxInfError, RelaxLenError, RelaxNaNError, RelaxNoModelError, RelaxNoPdbError, RelaxNoResError, RelaxNoSequenceError, RelaxNoTensorError, RelaxNoValueError, RelaxNoVectorsError, RelaxNucleusError, RelaxProtonTypeError, RelaxSpinTypeError