Source code for pacman.executor.algorithm_classes.abstract_algorithm

# Copyright (c) 2017-2019 The University of Manchester
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from six import add_metaclass
from spinn_utilities.abstract_base import AbstractBase, abstractmethod
from pacman.exceptions import PacmanConfigurationException


[docs]@add_metaclass(AbstractBase) class AbstractAlgorithm(object): """ Represents the metadata for an algorithm. """ __slots__ = [ # The ID of the algorithm; must be unique over all algorithms "_algorithm_id", # A list of inputs that must be provided "_required_inputs", # A list of inputs that can optionally be provided "_optional_inputs", # A list of output types "_outputs", # A list of required input tokens "_required_input_tokens", # A list of optional input tokens "_optional_input_tokens", # A list of generated output tokens "_generated_output_tokens" ] def __init__( self, algorithm_id, required_inputs, optional_inputs, outputs, required_input_tokens, optional_input_tokens, generated_output_tokens): """ :param algorithm_id: The unique ID of the algorithm :type algorithm_id: str :param required_inputs: The inputs required by the algorithm :type required_inputs: list(:py:class:`AbstractInput`) :param optional_inputs:\ The optional inputs for the algorithm, which will be provided\ when available :type optional_inputs: list(:py:class:`AbstractInput`) :param outputs: The output types of the algorithm :type outputs: list(:py:class:`Output`) :param required_input_tokens: Tokens required to have been generated\ before this algorithm can start :type required_input_tokens: list(:py:class:`Token`) :param optional_input_tokens: Tokens required to have been generated\ before this algorithm can start if and only if at least one\ algorithm generates the token :type optional_input_tokens: list(:py:class:`Token`) :param generated_output_tokens: Tokens generated by this algorithm :type generated_output_tokens: list(:py:class:`Token`) """ # pylint: disable=too-many-arguments self._algorithm_id = algorithm_id self._required_inputs = required_inputs self._optional_inputs = optional_inputs self._outputs = outputs self._required_input_tokens = required_input_tokens self._optional_input_tokens = optional_input_tokens self._generated_output_tokens = generated_output_tokens @property def algorithm_id(self): """ The ID for this algorithm """ return self._algorithm_id @property def required_inputs(self): """ The required inputs of the algorithm """ return self._required_inputs @property def optional_inputs(self): """ The optional inputs of the algorithm """ return self._optional_inputs @property def outputs(self): """ The outputs of the algorithm """ return self._outputs @property def required_input_tokens(self): """ The required input tokens of the algorithm """ return self._required_input_tokens @property def optional_input_tokens(self): """ The optional input tokens of the algorithm """ return self._optional_input_tokens @property def generated_output_tokens(self): """ The generated output tokens of the algorithm """ return self._generated_output_tokens def _get_inputs(self, inputs): """ Get the required and optional inputs out of the inputs :param inputs: A dict of input type to value :return: A dict of parameter name to value """ matches = dict() # Add required inputs, failing if they don't exist for required_input in self._required_inputs: match = required_input.get_inputs_by_name(inputs) if match is None: raise PacmanConfigurationException( "Missing required input {} of type {} for algorithm {}" .format( required_input.name, required_input.param_types, self._algorithm_id)) matches.update(match) # Add optional inputs if they exist for optional_input in self._optional_inputs: match = optional_input.get_inputs_by_name(inputs) if match is not None: matches.update(match) return matches def _get_outputs(self, inputs, outputs): """ Get the outputs as a dictionary from the given return values :param inputs: A dict of input type to value :param outputs: A list of values of length equal to self._outputs :return: A dict of output type to value """ return { output_def.output_type: output if output_def.file_name_type is None else inputs[output_def.file_name_type] for output_def, output in zip(self._outputs, outputs) }
[docs] @abstractmethod def call(self, inputs): """ Call the algorithm with the given inputs and return the outputs :param inputs: A dict of input type -> value :return: A dict of output type -> value """
[docs] @abstractmethod def write_provenance_header(self, provenance_file): """ Writes the header info for this algorithm So things like name, module, class, function and command_line_arguments But not anything about input and outputs as this is done elsewhere :param provenance_file: File to write to :type provenance_file: file """