diff --git a/data_specification/__init__.py b/data_specification/__init__.py index 7036e32..7b4eb69 100644 --- a/data_specification/__init__.py +++ b/data_specification/__init__.py @@ -16,50 +16,51 @@ """ Used to generate memory images for a SpiNNaker CPU core from a set of \ instructions. -The main part of this package is the \ -:py:class:`DataSpecificationGenerator` \ -class. This is used to generate a "Data Specification", which can then be \ -executed to produce a memory image. This package also handles this function \ -if required, through the \ +The main part of this package is the +:py:class:`DataSpecificationGenerator` +class. This is used to generate a "Data Specification", which can then be +executed to produce a memory image. This package also handles this function +if required, through the :py:class:`DataSpecificationExecutor` class. Functional Requirements ======================= -Creation of a Data Specification Language file which can be executed to \ +Creation of a Data Specification Language file which can be executed to produce a memory image. - * Any errors that can be checked during the creation of the \ - specification should throw an exception. +* Any errors that can be checked during the creation of the specification + should throw an exception. - * It will be impossible to detect all errors at creation time. +* It will be impossible to detect all errors at creation time. - * There should be no assumption of where the data specification will \ - be stored, although a default provision of a way to write the \ - specification to a file is acceptable. +* There should be no assumption of where the data specification will be + stored, although a default provision of a way to write the specification to + a file is acceptable. Execution of a Data Specification Language file, producing a memory image. - * This should detect any errors during execution and report them, \ - halting the execution. +* This should detect any errors during execution and report them, halting the + execution. - * There should be no assumption of where the data specification is \ - read from, although a default provision of a way to read the \ - specification from a file is acceptable. +* There should be no assumption of where the data specification is read from, + although a default provision of a way to read the specification from a file + is acceptable. Use Cases ========= There are a number of use-cases of this library: - * :py:class:`DataSpecificationGenerator` \ - is used to create a compressed memory image which can be expanded later, \ - to reduce the amount of data that needs to be transferred over a slow \ - connection. +* :py:class:`DataSpecificationGenerator` is used to create a compressed memory + image which can be expanded later, to reduce the amount of data that needs + to be transferred over a slow connection. - * :py:class:`DataSpecificationExecutor` \ - is used to execute a previously generated specification at the receiving \ - end of a slow connection. +* :py:class:`DataSpecificationExecutor` is used to execute a previously + generated specification at the receiving end of a slow connection. + +Main API +======== """ from data_specification._version import ( # noqa __version__, __version_name__, __version_month__, __version_year__) diff --git a/data_specification/data_specification_executor_functions.py b/data_specification/data_specification_executor_functions.py index c87cc6d..eac33dc 100644 --- a/data_specification/data_specification_executor_functions.py +++ b/data_specification/data_specification_executor_functions.py @@ -37,6 +37,10 @@ class DataSpecificationExecutorFunctions(AbstractExecutorFunctions): """ This class includes the function related to each of the commands\ of the data specification file. + + .. note:: + DSG operations not mentioned in this class will cause an error during + DSE if used. """ __slots__ = [ diff --git a/data_specification/data_specification_generator.py b/data_specification/data_specification_generator.py index fa3a8fc..1fe8530 100644 --- a/data_specification/data_specification_generator.py +++ b/data_specification/data_specification_generator.py @@ -2379,10 +2379,11 @@ def _write_command_to_files(self, cmd_word_list, cmd_string, indent=False, outdent=False, no_instruction_number=False): """ Writes the binary command to the binary output file and, if the\ user has requested a text output for debug purposes, also write\ - the text version to the text file.\ - Setting the optional parameter ``indent`` to True causes\ - subsequent commands to be indented by two spaces relative to this\ - one. Similarly, setting ``outdent`` to True, reverses this spacing. + the text version to the text file. + + Setting the optional parameter ``indent`` to ``True`` causes subsequent + commands to be indented by two spaces relative to this one. Similarly, + setting ``outdent`` to ``True`` reverses this spacing. :param bytearray cmd_word_list: list of binary words to be added to the binary data specification file @@ -2420,8 +2421,10 @@ def _write_command_to_files(self, cmd_word_list, cmd_string, indent=False, @property def region_sizes(self): - """ A list of sizes of each region that has been reserved. Note that\ - the list will include 0s for each non-reserved region. + """ A list of sizes of each region that has been reserved. + + .. note:: + The list will include ``0`` for each non-reserved region. :rtype: list(int) """ @@ -2430,7 +2433,7 @@ def region_sizes(self): @property def current_region(self): """ The ID of the current DSG region we're writing to.\ - If not yet writing to any region, None. + If not yet writing to any region, ``None``. :rtype: int or None """ diff --git a/data_specification/spi/abstract_executor_functions.py b/data_specification/spi/abstract_executor_functions.py index 7128a92..7b79cd5 100644 --- a/data_specification/spi/abstract_executor_functions.py +++ b/data_specification/spi/abstract_executor_functions.py @@ -29,6 +29,8 @@ def execute_break(self, cmd): # pragma: no cover """ This command raises an exception to stop the execution of the \ data spec executor (DSE). + Implements :py:obj:`~.BREAK` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -41,6 +43,8 @@ def execute_break(self, cmd): # pragma: no cover def execute_nop(self, cmd): """ This command executes no operation. + Implements :py:obj:`~.NOP` + :param int cmd: the command which triggered the function call :return: No value returned :rtype: None @@ -52,6 +56,8 @@ def execute_reserve(self, cmd): # pragma: no cover """ This command reserves a region and assigns some memory space \ to it. + Implements :py:obj:`~.RESERVE` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -64,6 +70,8 @@ def execute_reserve(self, cmd): # pragma: no cover def execute_free(self, cmd): # pragma: no cover """ This command frees some memory. + Implements :py:obj:`~.FREE` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -76,6 +84,8 @@ def execute_free(self, cmd): # pragma: no cover def execute_declare_rng(self, cmd): # pragma: no cover """ This command declares a random number generator. + Implements :py:obj:`~.DECLARE_RNG` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -88,6 +98,8 @@ def execute_declare_rng(self, cmd): # pragma: no cover def execute_random_dist(self, cmd): # pragma: no cover """ This command defines a random disribution. + Implements :py:obj:`~.DECLARE_RANDOM_DIST` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -100,6 +112,8 @@ def execute_random_dist(self, cmd): # pragma: no cover def execute_get_random_rumber(self, cmd): # pragma: no cover """ This command obtains a random number from a distribution. + Implements :py:obj:`~.GET_RANDOM_NUMBER` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -112,6 +126,8 @@ def execute_get_random_rumber(self, cmd): # pragma: no cover def execute_start_struct(self, cmd): # pragma: no cover """ This command starts to define a structure. + Implements :py:obj:`~.START_STRUCT` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -124,6 +140,8 @@ def execute_start_struct(self, cmd): # pragma: no cover def execute_struct_elem(self, cmd): # pragma: no cover """ This command adds an element to a structure. + Implements :py:obj:`~.STRUCT_ELEM` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -136,6 +154,8 @@ def execute_struct_elem(self, cmd): # pragma: no cover def execute_end_struct(self, cmd): # pragma: no cover """ This command completes the definition of a structure. + Implements :py:obj:`~.END_STRUCT` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -148,6 +168,8 @@ def execute_end_struct(self, cmd): # pragma: no cover def execute_start_constructor(self, cmd): # pragma: no cover """ This command starts the definition of a function. + Implements :py:obj:`~.START_CONSTRUCTOR` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -160,6 +182,8 @@ def execute_start_constructor(self, cmd): # pragma: no cover def execute_end_constructor(self, cmd): # pragma: no cover """ This command ends the definition of a function. + Implements :py:obj:`~.END_CONSTRUCTOR` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -172,6 +196,8 @@ def execute_end_constructor(self, cmd): # pragma: no cover def execute_construct(self, cmd): # pragma: no cover """ This command calls a function. + Implements :py:obj:`~.CONSTRUCT` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -184,6 +210,8 @@ def execute_construct(self, cmd): # pragma: no cover def execute_read(self, cmd): # pragma: no cover """ This command reads a word from memory. + Implements :py:obj:`~.READ` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -198,6 +226,8 @@ def execute_write(self, cmd): # pragma: no cover number of times as identified by either a value in the command \ or a register value. + Implements :py:obj:`~.WRITE` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -210,6 +240,8 @@ def execute_write(self, cmd): # pragma: no cover def execute_write_array(self, cmd): # pragma: no cover """ This command writes an array of values in the specified region. + Implements :py:obj:`~.WRITE_ARRAY` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -222,6 +254,8 @@ def execute_write_array(self, cmd): # pragma: no cover def execute_write_struct(self, cmd): # pragma: no cover """ This command writes a structure to memory. + Implements :py:obj:`~.WRITE_STRUCT` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -235,6 +269,8 @@ def execute_block_copy(self, cmd): # pragma: no cover """ This command copies a block of memory from one location to \ another. + Implements :py:obj:`~.BLOCK_COPY` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -248,6 +284,8 @@ def execute_switch_focus(self, cmd): # pragma: no cover """ This command switches the focus to the desired, already allocated,\ memory region. + Implements :py:obj:`~.SWITCH_FOCUS` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -260,6 +298,8 @@ def execute_switch_focus(self, cmd): # pragma: no cover def execute_loop(self, cmd): # pragma: no cover """ This command starts a loop. + Implements :py:obj:`~.LOOP` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -272,6 +312,8 @@ def execute_loop(self, cmd): # pragma: no cover def execute_break_loop(self, cmd): # pragma: no cover """ This command stops a loop early. + Implements :py:obj:`~.BREAK_LOOP` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -284,6 +326,8 @@ def execute_break_loop(self, cmd): # pragma: no cover def execute_end_loop(self, cmd): # pragma: no cover """ This command finishes a loop. + Implements :py:obj:`~.END_LOOP` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -296,6 +340,8 @@ def execute_end_loop(self, cmd): # pragma: no cover def execute_if(self, cmd): # pragma: no cover """ This command does a conditional branch. + Implements :py:obj:`~.IF` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -308,6 +354,8 @@ def execute_if(self, cmd): # pragma: no cover def execute_else(self, cmd): # pragma: no cover """ This command handles the other branch of a conditional. + Implements :py:obj:`~.ELSE` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -320,6 +368,8 @@ def execute_else(self, cmd): # pragma: no cover def execute_end_if(self, cmd): # pragma: no cover """ This command ends a conditional. + Implements :py:obj:`~.END_IF` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -333,6 +383,8 @@ def execute_mv(self, cmd): # pragma: no cover """ This command moves an immediate value to a register or copies the \ value of a register to another register. + Implements :py:obj:`~.MV` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -345,6 +397,8 @@ def execute_mv(self, cmd): # pragma: no cover def execute_get_wr_ptr(self, cmd): # pragma: no cover """ This command gets the current write pointer. + Implements :py:obj:`~.GET_WR_PTR` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -357,6 +411,8 @@ def execute_get_wr_ptr(self, cmd): # pragma: no cover def execute_set_wr_ptr(self, cmd): # pragma: no cover """ This command sets the current write pointer. + Implements :py:obj:`~.SET_WR_PTR` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -383,6 +439,8 @@ def execute_align_wr_ptr(self, cmd): # pragma: no cover """ This command moves the write pointer to be at the start of the \ next word if it isn't already at the start of a word. + Implements :py:obj:`~.ALIGN_WR_PTR` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -395,6 +453,8 @@ def execute_align_wr_ptr(self, cmd): # pragma: no cover def execute_arith_op(self, cmd): # pragma: no cover """ This command performs an arithmetic operation. + Implements :py:obj:`~.ARITH_OP` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -407,6 +467,8 @@ def execute_arith_op(self, cmd): # pragma: no cover def execute_logic_op(self, cmd): # pragma: no cover """ This command performs a logical operation. + Implements :py:obj:`~.LOGIC_OP` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -419,6 +481,8 @@ def execute_logic_op(self, cmd): # pragma: no cover def execute_reformat(self, cmd): # pragma: no cover """ This command is never generated! + Implements :py:obj:`~.REFORMAT` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -431,6 +495,8 @@ def execute_reformat(self, cmd): # pragma: no cover def execute_copy_struct(self, cmd): # pragma: no cover """ This command copies a structure from one slot to another. + Implements :py:obj:`~.COPY_STRUCT` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -444,6 +510,8 @@ def execute_copy_param(self, cmd): # pragma: no cover """ This command copies a field of a structure to another field of \ a possibly-different structure. + Implements :py:obj:`~.COPY_PARAM` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -456,6 +524,8 @@ def execute_copy_param(self, cmd): # pragma: no cover def execute_write_param(self, cmd): # pragma: no cover """ This command handles a single element of a structure. + Implements :py:obj:`~.WRITE_PARAM` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -468,6 +538,8 @@ def execute_write_param(self, cmd): # pragma: no cover def execute_write_param_component(self, cmd): # pragma: no cover """ This command is never generated! + Implements :py:obj:`~.WRITE_PARAM_COMPONENT` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -480,6 +552,8 @@ def execute_write_param_component(self, cmd): # pragma: no cover def execute_print_val(self, cmd): # pragma: no cover """ This command prints a value to the log. + Implements :py:obj:`~.PRINT_VAL` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -492,6 +566,8 @@ def execute_print_val(self, cmd): # pragma: no cover def execute_print_txt(self, cmd): # pragma: no cover """ This command prints a short string to the log. + Implements :py:obj:`~.PRINT_TXT` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -504,6 +580,8 @@ def execute_print_txt(self, cmd): # pragma: no cover def execute_print_struct(self, cmd): # pragma: no cover """ This command prints a structure to the log. + Implements :py:obj:`~.PRINT_STRUCT` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -516,6 +594,8 @@ def execute_print_struct(self, cmd): # pragma: no cover def execute_read_param(self, cmd): # pragma: no cover """ This command extracts an element from a structure. + Implements :py:obj:`~.READ_PARAM` + :param int cmd: the command which triggered the function call :return: No value returned :raise DataSpecificationSyntaxError:\ @@ -528,6 +608,8 @@ def execute_read_param(self, cmd): # pragma: no cover def execute_end_spec(self, cmd): # pragma: no cover """ This command marks the end of the specification program. + Implements :py:obj:`~.END_SPEC` + :param int cmd: the command which triggered the function call :return: A special marker to signal the end. :raise DataSpecificationSyntaxError:\ diff --git a/doc/source/conf.py b/doc/source/conf.py index ca2e934..7cae536 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -29,7 +29,6 @@ # import sys import os -from sphinx import apidoc # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -53,7 +52,7 @@ intersphinx_mapping = { 'python': ('https://docs.python.org/3.6', None), - 'numpy': ("https://docs.scipy.org/doc/numpy/", None), + 'numpy': ("https://numpy.org/doc/stable/", None), 'spinn_machine': ( 'https://spinnmachine.readthedocs.io/en/latest/', None), } @@ -363,8 +362,43 @@ if (os.path.isfile(f) and f.endswith( ".rst") and f != "index.rst" and f != "modules.rst"): os.remove(f) -apidoc.main([None, '-o', ".", "../../data_specification", - # Exclusions - "../../data_specification/[dm]*.py", - "../../data_specification/spi/a*.py", - "../../data_specification/enums/[a-z]*.py"]) + + +# We want to document __call__ when encountered +autodoc_default_options = { + "members": True, + "special-members": "__call__" +} + + +def filtered_files(base, excludes=None): + if not excludes: + excludes = [] + for root, _dirs, files in os.walk(base): + for filename in files: + if filename.endswith(".py") and not filename.startswith("_"): + full = root + "/" + filename + if full not in excludes: + yield full + + +# UGH! +output_dir = os.path.abspath(".") +os.chdir("../..") + +# We only document __init__.py files... except for these special cases. +# Use the unix full pathname from the root of the checked out repo +explicit_wanted_files = [ + "data_specification/constants.py", + "data_specification/utility_calls.py", + "data_specification/exceptions.py"] +options = ['-o', output_dir, "data_specification"] +options.extend(filtered_files("data_specification", explicit_wanted_files)) +try: + # Old style API; Python 2.7 + from sphinx import apidoc + options = [None] + options +except ImportError: + # New style API; Python 3.6 onwards + from sphinx.ext import apidoc +apidoc.main(options) diff --git a/doc/source/index.rst b/doc/source/index.rst index 6b25e10..7382258 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1,21 +1,20 @@ These pages document the python code for the DataSpecification_ module which is part of the SpiNNaker_ Project. -This code depends on SpiNNUtils_, SpiNNMachine_ and SpiNNStorageHandlers_ (Combined_documentation_). +This code depends on SpiNNUtils_ and SpiNNMachine_ (Combined_documentation_). .. _SpiNNaker: http://apt.cs.manchester.ac.uk/projects/SpiNNaker/ .. _DataSpecification: https://github.com/SpiNNakerManchester/DataSpecification .. _SpiNNUtils: http://spinnutils.readthedocs.io .. _SpiNNMachine: http://spinnmachine.readthedocs.io -.. _SpiNNStorageHandlers: http://spinnstoragehandlers.readthedocs.io .. _Combined_documentation: http://spinnakermanchester.readthedocs.io - Data Specification ================== .. automodule:: data_specification :special-members: + :noindex: Contents -------- @@ -25,11 +24,9 @@ Contents modules - Indices and tables ------------------ * :ref:`genindex` * :ref:`modindex` * :ref:`search` -