def __call__(self, func): """ Parse and set the mpi parameters within the task core element. :param func: Function to decorate :return: Decorated function. """ if not self.scope: # from pycompss.api.dummy.mpi import mpi as dummy_mpi # d_m = dummy_mpi(self.args, self.kwargs) # return d_m.__call__(func) raise Exception( "The mpi decorator only works within PyCOMPSs framework.") if i_am_at_master(): # master code from pycompss.runtime.binding import register_ce mod = inspect.getmodule(func) self.module = mod.__name__ # not func.__module__ if (self.module == '__main__' or self.module == 'pycompss.runtime.launch'): # The module where the function is defined was run as __main__, # we need to find out the real module name. # path=mod.__file__ # dirs=mod.__file__.split(os.sep) # file_name=os.path.splitext(os.path.basename(mod.__file__))[0] # Get the real module name from our launch.py variable path = getattr(mod, "app_path") dirs = path.split(os.path.sep) file_name = os.path.splitext(os.path.basename(path))[0] mod_name = file_name i = len(dirs) - 1 while i > 0: new_l = len(path) - (len(dirs[i]) + 1) path = path[0:new_l] if "__init__.py" in os.listdir(path): # directory is a package i -= 1 mod_name = dirs[i] + '.' + mod_name else: break self.module = mod_name # Include the registering info related to @MPI # Retrieve the base coreElement established at @task decorator coreElement = func.__to_register__ # Update the core element information with the mpi information coreElement.set_implType("MPI") binary = self.kwargs['binary'] if 'workingDir' in self.kwargs: workingDir = self.kwargs['workingDir'] else: workingDir = '[unassigned]' # Empty or '[unassigned]' runner = self.kwargs['runner'] implSignature = 'MPI.' + binary coreElement.set_implSignature(implSignature) implArgs = [binary, workingDir, runner] coreElement.set_implTypeArgs(implArgs) func.__to_register__ = coreElement # Do the task register if I am the top decorator if func.__who_registers__ == __name__: if __debug__: logger.debug( "[@MPI] I have to do the register of function %s in module %s" % (func.__name__, self.module)) register_ce(coreElement) else: # worker code pass @wraps(func) def mpi_f(*args, **kwargs): # This is executed only when called. if __debug__: logger.debug("Executing mpi_f wrapper.") # Set the computingNodes variable in kwargs for its usage # in @task decorator kwargs['computingNodes'] = self.kwargs['computingNodes'] if len(args) > 0: # The 'self' for a method function is passed as args[0] slf = args[0] # Replace and store the attributes saved = {} for k, v in self.kwargs.items(): if hasattr(slf, k): saved[k] = getattr(slf, k) setattr(slf, k, v) # Call the method ret = func(*args, **kwargs) if len(args) > 0: # Put things back for k, v in saved.items(): setattr(slf, k, v) return ret mpi_f.__doc__ = func.__doc__ return mpi_f
def __call__(self, func): if i_am_at_master(): # master code mod = inspect.getmodule(func) self.module = mod.__name__ # not func.__module__ if(self.module == '__main__' or self.module == 'pycompss.runtime.launch'): # The module where the function is defined was run as __main__, # we need to find out the real module name. # path=mod.__file__ # dirs=mod.__file__.split(os.sep) # file_name=os.path.splitext(os.path.basename(mod.__file__))[0] # Get the real module name from our launch.py variable path = getattr(mod, "app_path") dirs = path.split(os.path.sep) file_name = os.path.splitext(os.path.basename(path))[0] mod_name = file_name i = len(dirs) - 1 while i > 0: new_l = len(path) - (len(dirs[i]) + 1) path = path[0:new_l] if "__init__.py" in os.listdir(path): # directory is a package i -= 1 mod_name = dirs[i] + '.' + mod_name else: break self.module = mod_name # Include the registering info related to @constraint # Retrieve the base coreElement established at @task decorator coreElement = func.__to_register__ # Update the core element information with the constraints coreElement.set_implConstraints(self.kwargs) func.__to_register__ = coreElement # Do the task register if I am the top decorator if func.__who_registers__ == __name__: logger.debug("[@CONSTRAINT] I have to do the register of function %s in module %s" % (func.__name__, self.module)) register_ce(coreElement) else: # worker code pass @wraps(func) def constrained_f(*args, **kwargs): # This is executed only when called. logger.debug("Executing constrained_f wrapper.") if len(args) > 0: # The 'self' for a method function is passed as args[0] slf = args[0] # Replace and store the attributes saved = {} for k, v in self.kwargs.items(): if hasattr(slf, k): saved[k] = getattr(slf, k) setattr(slf, k, v) # Call the method ret = func(*args, **kwargs) if len(args) > 0: # Put things back for k, v in saved.items(): setattr(slf, k, v) return ret constrained_f.__doc__ = func.__doc__ return constrained_f
def __call__(self, func): """ Parse and set the implementation parameters within the task core element. :param func: Function to decorate :return: Decorated function. """ if not self.scope: # from pycompss.api.dummy.implement import implement as dummy_implement # d_i = dummy_implement(self.args, self.kwargs) # return d_i.__call__(func) raise Exception("The implement decorator only works within PyCOMPSs framework.") if i_am_at_master(): # master code from pycompss.runtime.binding import register_ce mod = inspect.getmodule(func) self.module = mod.__name__ # not func.__module__ if(self.module == '__main__' or self.module == 'pycompss.runtime.launch'): # The module where the function is defined was run as __main__, # we need to find out the real module name. # path=mod.__file__ # dirs=mod.__file__.split(os.sep) # file_name=os.path.splitext(os.path.basename(mod.__file__))[0] # Get the real module name from our launch.py variable path = getattr(mod, "app_path") dirs = path.split(os.path.sep) file_name = os.path.splitext(os.path.basename(path))[0] mod_name = file_name i = len(dirs) - 1 while i > 0: new_l = len(path) - (len(dirs[i]) + 1) path = path[0:new_l] if "__init__.py" in os.listdir(path): # directory is a package i -= 1 mod_name = dirs[i] + '.' + mod_name else: break self.module = mod_name # Include the registering info related to @MPI # Retrieve the base coreElement established at @task decorator coreElement = func.__to_register__ # Update the core element information with the mpi information ce_signature = coreElement.get_ce_signature() implSignature = ce_signature coreElement.set_implSignature(implSignature) anotherClass = self.kwargs['source_class'] anotherMethod = self.kwargs['method'] ce_signature = anotherClass + '.' + anotherMethod coreElement.set_ce_signature(ce_signature) # This is not needed since the arguments are already set by the # task decorator. # implArgs = [anotherClass, anotherMethod] # coreElement.set_implTypeArgs(implArgs) coreElement.set_implType("METHOD") func.__to_register__ = coreElement # Do the task register if I am the top decorator if func.__who_registers__ == __name__: if __debug__: logger.debug("[@IMPLEMENT] I have to do the register of function %s in module %s" % (func.__name__, self.module)) register_ce(coreElement) else: # worker code pass @wraps(func) def implement_f(*args, **kwargs): # This is executed only when called. if __debug__: logger.debug("Executing implement_f wrapper.") # The 'self' for a method function is passed as args[0] slf = args[0] # Replace and store the attributes saved = {} for k, v in self.kwargs.items(): if hasattr(slf, k): saved[k] = getattr(slf, k) setattr(slf, k, v) # Call the method ret = func(*args, **kwargs) # Put things back for k, v in saved.items(): setattr(slf, k, v) return ret implement_f.__doc__ = func.__doc__ return implement_f
def registerTask(f, module, is_instance): """ This function is used to register the task in the runtime. This registration must be done only once on the task decorator initialization. :param f: Function to be registered :param module: Module that the function belongs to. """ # Look for the decorator that has to do the registration # Since the __init__ of the decorators is independent, there is no way # to pass information through them. # However, the __call__ method of the decorators can be used. # The way that they are called is from bottom to top. So, the first one to # call its __call__ method will always be @task. Consequently, the @task # decorator __call__ method can detect the top decorator and pass a hint # to order that decorator that has to do the registration (not the others). gotFuncCode = False func = f while not gotFuncCode: try: funcCode = inspect.getsourcelines(func) gotFuncCode = True except IOError: # There is one or more decorators below the @task --> undecorate # until possible to get the func code. # Example of this case: test 19: @timeit decorator below the # @task decorator. func = func.__wrapped__ decoratorKeys = ("implement", "constraint", "decaf", "mpi", "ompss", "binary", "opencl", "task") topDecorator = getTopDecorator(funcCode, decoratorKeys) logger.debug("[@TASK] Top decorator of function %s in module %s: %s" % (f.__name__, module, str(topDecorator))) f.__who_registers__ = topDecorator # not usual tasks - handled by the runtime without invoking the PyCOMPSs # worker. Needed to filter in order not to code the strings when using # them in these type of tasks filter = ("decaf", "mpi", "ompss", "binary", "opencl") default = 'task' taskType = getTaskType(funcCode, decoratorKeys, filter, default) logger.debug("[@TASK] Task type of function %s in module %s: %s" % (f.__name__, module, str(taskType))) f.__task_type__ = taskType if taskType == default: f.__code_strings__ = True else: f.__code_strings__ = False # Include the registering info related to @task ins = inspect.getouterframes(inspect.currentframe()) # I know that this is ugly, but I see no other way to get the class name class_name = ins[2][3] # I know that this is ugly, but I see no other way to check if it is a # classs method. is_classmethod = class_name != '<module>' if is_instance or is_classmethod: ce_signature = module + "." + class_name + '.' + f.__name__ implTypeArgs = [module + "." + class_name, f.__name__] else: ce_signature = module + "." + f.__name__ implTypeArgs = [module, f.__name__] implSignature = ce_signature implConstraints = {} implType = "METHOD" coreElement = CE(ce_signature, implSignature, implConstraints, implType, implTypeArgs) f.__to_register__ = coreElement # Do the task register if I am the top decorator if f.__who_registers__ == __name__: logger.debug( "[@TASK] I have to do the register of function %s in module %s" % (f.__name__, module)) logger.debug("[@TASK] %s" % str(f.__to_register__)) binding.register_ce(coreElement)
def __call__(self, func): if i_am_at_master(): # master code mod = inspect.getmodule(func) self.module = mod.__name__ # not func.__module__ if (self.module == '__main__' or self.module == 'pycompss.runtime.launch'): # The module where the function is defined was run as __main__, # we need to find out the real module name. # path=mod.__file__ # dirs=mod.__file__.split(os.sep) # file_name=os.path.splitext(os.path.basename(mod.__file__))[0] # Get the real module name from our launch.py variable path = getattr(mod, "app_path") dirs = path.split(os.path.sep) file_name = os.path.splitext(os.path.basename(path))[0] mod_name = file_name i = len(dirs) - 1 while i > 0: new_l = len(path) - (len(dirs[i]) + 1) path = path[0:new_l] if "__init__.py" in os.listdir(path): # directory is a package i -= 1 mod_name = dirs[i] + '.' + mod_name else: break self.module = mod_name # Include the registering info related to @MPI # Retrieve the base coreElement established at @task decorator coreElement = func.__to_register__ # Update the core element information with the mpi information coreElement.set_implType("DECAF") if 'workingDir' in self.kwargs: workingDir = self.kwargs['workingDir'] else: workingDir = '[unassigned]' # Empty or '[unassigned]' if 'mpiRunner' in self.kwargs: runner = self.kwargs['mpiRunner'] else: runner = 'mpirun' dfScript = self.kwargs['dfScript'] if 'dfExecutor' in self.kwargs: dfExecutor = self.kwargs['dfExecutor'] else: dfExecutor = '[unassigned]' # Empty or '[unassigned]' if 'dfLib' in self.kwargs: dfLib = self.kwargs['dfLib'] else: dfLib = '[unassigned]' # Empty or '[unassigned]' implSignature = 'DECAF.' + dfScript coreElement.set_implSignature(implSignature) implArgs = [dfScript, dfExecutor, dfLib, workingDir, runner] coreElement.set_implTypeArgs(implArgs) func.__to_register__ = coreElement # Do the task register if I am the top decorator if func.__who_registers__ == __name__: logger.debug( "[@DECAF] I have to do the register of function %s in module %s" % (func.__name__, self.module)) register_ce(coreElement) else: # worker code pass @wraps(func) def decaf_f(*args, **kwargs): # This is executed only when called. logger.debug("Executing decaf_f wrapper.") # Set the computingNodes variable in kwargs for its usage in @task decorator kwargs['computingNodes'] = self.kwargs['computingNodes'] if len(args) > 0: # The 'self' for a method function is passed as args[0] slf = args[0] # Replace and store the attributes saved = {} for k, v in self.kwargs.items(): if hasattr(slf, k): saved[k] = getattr(slf, k) setattr(slf, k, v) # Call the method ret = func(*args, **kwargs) if len(args) > 0: # Put things back for k, v in saved.items(): setattr(slf, k, v) return ret decaf_f.__doc__ = func.__doc__ return decaf_f