def __new__(mcs, name, bases, attrs): # pylint: disable=no-member pm = armi.getPluginManager() if pm is None: runLog.warning( "Blueprints were instantiated before the framework was " "configured with plugins. Blueprints cannot be imported before " "ARMI has been configured." ) else: pluginSections = pm.hook.defineBlueprintsSections() for plug in pluginSections: for (attrName, section, resolver) in plug: assert isinstance(section, yamlize.Attribute) if attrName in attrs: raise plugins.PluginError( "There is already a section called '{}' in the reactor " "blueprints".format(attrName) ) attrs[attrName] = section attrs["_resolveFunctions"].append(resolver) newType = yamlize.objects.ObjectType.__new__(mcs, name, bases, attrs) return newType
def dependencies(self): """ Get a list of parent Case objects. Notes ----- This is performed on demand so that if someone changes the underlying Settings, the case will reflect the correct dependencies. As a result, if this is being done iteratively, you may want to cache it somehow (in a dict?). Ideally, this should not be the responsibility of the Case, but rather the suite! """ dependencies = set() if self._caseSuite is not None: pm = getPluginManager() if pm is not None: for pluginDependencies in pm.hook.defineCaseDependencies( case=self, suite=self._caseSuite): dependencies.update(pluginDependencies)
def __init__(self): from armi import getPluginManager # pylint: disable=import-outside-toplevel self._entryPoints = dict() for pluginEntryPoints in getPluginManager().hook.defineEntryPoints(): for entryPoint in pluginEntryPoints: if entryPoint.name in self._entryPoints: raise KeyError( "Duplicate entry points defined for `{}`: {} and {}". format( entryPoint.name, self._entryPoints[entryPoint.name], entryPoint, )) self._entryPoints[entryPoint.name] = entryPoint parser = ArmiParser( prog=context.APP_NAME, description=self.__doc__, usage="%(prog)s [-h] [-l | command [args]]", ) group = parser.add_mutually_exclusive_group() group.add_argument("-v", "--version", action="store_true", help="display the version") group.add_argument("-l", "--list-commands", action="store_true", help="list commands") group.add_argument("command", nargs="?", default="help", help=argparse.SUPPRESS) parser.add_argument("args", nargs=argparse.REMAINDER, help=argparse.SUPPRESS) self.parser = parser
def __init__(self): self._entryPoints = dict() for pluginEntryPoints in armi.getPluginManager( ).hook.defineEntryPoints(): for entryPoint in pluginEntryPoints: if entryPoint.name in self._entryPoints: raise KeyError( "Duplicate entry points defined for `{}`: {} and {}". format( entryPoint.name, self._entryPoints[entryPoint.name], entryPoint, )) self._entryPoints[entryPoint.name] = entryPoint parser = argparse.ArgumentParser( prog="armi", description=self.__doc__, usage="%(prog)s [-h] [-l | command [args]]", ) group = parser.add_mutually_exclusive_group() group.add_argument("-v", "--version", action="version", version="%(prog)s " + armi.__version__) group.add_argument("-l", "--list-commands", action="store_true", help="list commands") group.add_argument("command", nargs="?", default="help", help=argparse.SUPPRESS) parser.add_argument("args", nargs=argparse.REMAINDER, help=argparse.SUPPRESS) self.parser = parser
def workerOperate(self): """ The main loop on any worker MPI nodes. Notes ----- This method is what worker nodes are in while they wait for instructions from the master node in a parallel run. The nodes will sit, waiting for a "worker command". When this comes (from a bcast from the master), a set of if statements are evaluated, with specific behaviors defined for each command. If the operator doesn't understand the command, it loops through the interface stack to see if any of the interfaces understand it. Originally, "magic strings" were broadcast, which were handled either here or in one of the interfaces' ``workerOperate`` methods. Since then, the :py:mod:`~armi.mpiActions` system has been devised which just broadcasts ``MpiAction`` objects. Both methods are still supported. See Also -------- armi.mpiActions : MpiAction information armi.interfaces.workerOperate : interface-level handling of worker commands. """ while True: # sit around waiting for a command from the master runLog.extra("Node {0} ready and waiting".format(armi.MPI_RANK)) cmd = armi.MPI_COMM.bcast(None, root=0) runLog.extra("worker received command {0}".format(cmd)) # got a command. go use it. if isinstance(cmd, mpiActions.MpiAction): cmd.invoke(self, self.r, self.cs) elif cmd == "quit": self.workerQuit() break # If this break is removed, the program will remain in the while loop forever. elif cmd == "finished": runLog.warning( "Received unexpected FINISHED command. Usually a QUIT command precedes this. " "Skipping cleanup of temporary files.") break elif cmd == "sync": # wait around for a sync runLog.debug("Worker syncing") note = armi.MPI_COMM.bcast("wait", root=0) if note != "wait": raise RuntimeError( 'did not get "wait". Got {0}'.format(note)) else: # we don't understand the command on our own. check the interfaces # this allows all interfaces to have their own custom operation code. handled = False for i in self.interfaces: handled = i.workerOperate(cmd) if handled: break if not handled: if armi.MPI_RANK == 0: print("Interfaces" + str(self.interfaces)) runLog.error( "No interface understood worker command {0}\n check stdout for err\n" "available interfaces:\n {1}".format( cmd, "\n ".join("name:{} typeName:{} {}".format( i.name, i.function, i) for i in self.interfaces), )) raise RuntimeError( "Failed to delegate worker command {} to an interface." .format(cmd)) pm = armi.getPluginManager() resetFlags = pm.hook.mpiActionRequiresReset(cmd=cmd) # only reset if all the plugins agree to reset if all(resetFlags): self._resetWorker() # might be an mpi action which has a reactor and everything, preventing # garbage collection del cmd gc.collect()
def _loadPluginSettings(self): # The optionsCache stores options that may have come from a plugin before the # setting to which they apply. Whenever a new setting is added, we check to see # if there are any options in the cache, popping them out and adding them to the # setting. If all plugins' settings have been processed and the cache is not # empty, that's an error, because a plugin must have provided options to a # setting that doesn't exist. optionsCache = collections.defaultdict(list) defaultsCache = {} pm = armi.getPluginManager() if pm is None: runLog.warning("no plugin manager defined when settings were made") return for pluginSettings in pm.hook.defineSettings(): for pluginSetting in pluginSettings: if isinstance(pluginSetting, setting2.Setting): name = pluginSetting.name if name in self.settings: raise ValueError( f"The setting {pluginSetting.name} " "already exists and cannot be redefined.") self.settings[name] = pluginSetting # handle when new setting has modifier in the cache (modifier loaded first) if name in optionsCache: self.settings[name].addOptions(optionsCache.pop(name)) if name in defaultsCache: self.settings[name].changeDefault( defaultsCache.pop(name)) elif isinstance(pluginSetting, setting2.Option): if pluginSetting.settingName in self.settings: # modifier loaded after setting, so just apply it (no cache needed) self.settings[pluginSetting.settingName].addOption( pluginSetting) else: # no setting yet, cache it and apply when it arrives optionsCache[pluginSetting.settingName].append( pluginSetting) elif isinstance(pluginSetting, setting2.Default): if pluginSetting.settingName in self.settings: # modifier loaded after setting, so just apply it (no cache needed) self.settings[pluginSetting.settingName].changeDefault( pluginSetting) else: # no setting yet, cache it and apply when it arrives defaultsCache[ pluginSetting.settingName] = pluginSetting else: raise TypeError( f"Invalid setting definition found: {pluginSetting}") if optionsCache: raise ValueError( "The following options were provided for settings that do " "not exist. Make sure that the set of active plugins is " "consistent.\n{}".format(optionsCache)) if defaultsCache: raise ValueError( "The following defaults were provided for settings that do " "not exist. Make sure that the set of active plugins is " "consistent.\n{}".format(defaultsCache))