Exemplo n.º 1
0
    def handle_input_path(cls, path) -> None:
        """
        Sets cls.paths_to_compilation_units with a list of absolute paths to NESTML files.

        Use glob to search directories recursively.
        """
        cls.provided_input_path = path

        if not path or path == ['']:
            # mandatory path arg has not been handed over
            code, message = Messages.get_input_path_not_found(path="")
            Logger.log_message(code=code,
                               message=message,
                               log_level=LoggingLevel.ERROR)
            raise InvalidPathException(message)

        if type(path) is str:
            path = [path]

        cls.paths_to_compilation_units = list()
        for _path in path:
            if not os.path.isabs(_path):
                # turn relative to absolute path
                pynestml_dir = os.getcwd()
                _path = os.path.join(pynestml_dir, _path)

            if os.path.isfile(_path):
                cls.paths_to_compilation_units.append(_path)
            elif os.path.isdir(_path):
                for fn in glob.glob(os.path.join(_path, "**", "*.nestml"),
                                    recursive=True):
                    cls.paths_to_compilation_units.append(
                        os.path.join(_path, fn))
            else:
                # input_path should be either a file or a directory
                code, message = Messages.get_input_path_not_found(path=_path)
                Logger.log_message(code=code,
                                   message=message,
                                   log_level=LoggingLevel.ERROR)
                raise InvalidPathException(message)

        if not cls.paths_to_compilation_units:
            code, message = Messages.get_no_files_in_input_path(" ".join(path))
            Logger.log_message(code=code,
                               message=message,
                               log_level=LoggingLevel.ERROR)
            raise InvalidPathException(message)

        Logger.log_message(message="List of files that will be processed:",
                           log_level=LoggingLevel.INFO)
        for fn in cls.paths_to_compilation_units:
            Logger.log_message(message=fn, log_level=LoggingLevel.INFO)
Exemplo n.º 2
0
    def handle_input_path(cls, path):
        if path is None or path == '':
            # check if the mandatory path arg has been handed over, just terminate
            raise InvalidPathException('No input path specified.')

        cls.paths_to_compilation_units = list()
        if os.path.isabs(path):
            cls.provided_path = path
        else:
            # a relative path, reconstruct it. get the parent dir where models, pynestml etc. is located
            pynestml_dir = os.getcwd()
            cls.provided_path = os.path.join(pynestml_dir, path)

        if os.path.isfile(cls.provided_path):
            cls.paths_to_compilation_units.append(cls.provided_path)
        elif os.path.isdir(cls.provided_path):
            for filename in os.listdir(cls.provided_path):
                if filename.endswith('.nestml'):
                    cls.paths_to_compilation_units.append(
                        os.path.join(cls.provided_path, filename))
        else:
            # input_path should be either a file or a directory
            code, message = Messages.get_input_path_not_found(
                path=cls.provided_path)
            Logger.log_message(code=code,
                               message=message,
                               log_level=LoggingLevel.ERROR)
            raise Exception(message)
Exemplo n.º 3
0
    def handle_install_path(cls, path):
        if path is None:
            return

        if os.path.isabs(path):
            cls.install_path = path
        else:
            cls.install_path = os.path.abspath(path)

        # check if the installation path exists
        if not os.path.isdir(path):
            raise (InvalidPathException("Installation path \"" + str(path) +
                                        "\" not found."))
Exemplo n.º 4
0
 def handle_source_path(cls, path):
     # check if a target has been selected, otherwise set the buildNest as target
     if path is None:
         # check if the mandatory path arg has been handed over, just terminate
         raise InvalidPathException('Invalid source path!')
     else:
         cls.paths_to_compilation_units = list()
         if os.path.isabs(path):
             cls.provided_path = path
         # a relative path, reconstruct it. get the parent dir where models, pynestml etc. is located
         else:
             pynestml_dir = os.getcwd()
             cls.provided_path = os.path.join(pynestml_dir, path)
         if os.path.isfile(cls.provided_path):
             cls.paths_to_compilation_units.append(cls.provided_path)
         elif os.path.isdir(cls.provided_path):
             for filename in os.listdir(cls.provided_path):
                 if filename.endswith(".nestml"):
                     cls.paths_to_compilation_units.append(os.path.join(cls.provided_path, filename))
         else:
             cls.paths_to_compilation_units = cls.provided_path
Exemplo n.º 5
0
def install_nest(target_path: str, nest_path: str) -> None:
    """
    This method can be used to build the generated code and install the resulting extension module into NEST.

    Parameters
    ----------
    target_path : str
        Path to the target directory, which should contain the generated code artifacts (target platform code and CMake configuration file).
    nest_path : str
        Path to the NEST installation, which should point to the main directory where NEST is installed. This folder contains the ``bin``, ``lib(64)``, ``include``, and ``share`` folders of the NEST install. The ``bin`` folder should contain the ``nest-config`` script, which is accessed by NESTML to perform the installation. This path is the same as that passed through the ``-Dwith-nest`` argument of the CMake command before building the generated NEST module. The suffix ``bin/nest-config`` will be automatically appended to ``nest_path``.

    Raises
    ------
    GeneratedCodeBuildException
        If any kind of failure occurs during cmake configuration, build, or install.
    InvalidPathException
        If a failure occurs while trying to access the target path or the NEST installation path.
    """
    if not os.path.isdir(target_path):
        raise InvalidPathException('Target path (' + target_path +
                                   ') is not a directory!')

    if not os.path.isdir(nest_path):
        raise InvalidPathException('NEST path (' + nest_path +
                                   ') is not a directory!')

    cmake_cmd = [
        'cmake',
        '-Dwith-nest=' + os.path.join(nest_path, 'bin', 'nest-config'), '.'
    ]
    make_all_cmd = ['make', 'all']
    make_install_cmd = ['make', 'install']

    # check if we run on win
    if sys.platform.startswith('win'):
        shell = True
    else:
        shell = False

    # first call cmake with all the arguments
    try:
        result = subprocess.check_call(cmake_cmd,
                                       stderr=subprocess.STDOUT,
                                       shell=shell,
                                       cwd=str(os.path.join(target_path)))
    except subprocess.CalledProcessError as e:
        raise GeneratedCodeBuildException(
            'Error occurred during \'cmake\'! More detailed error messages can be found in stdout.'
        )

    # now execute make all
    try:
        subprocess.check_call(make_all_cmd,
                              stderr=subprocess.STDOUT,
                              shell=shell,
                              cwd=str(os.path.join(target_path)))
    except subprocess.CalledProcessError as e:
        raise GeneratedCodeBuildException(
            'Error occurred during \'make all\'! More detailed error messages can be found in stdout.'
        )

    # finally execute make install
    try:
        subprocess.check_call(make_install_cmd,
                              stderr=subprocess.STDOUT,
                              shell=shell,
                              cwd=str(os.path.join(target_path)))
    except subprocess.CalledProcessError as e:
        raise GeneratedCodeBuildException(
            'Error occurred during \'make install\'! More detailed error messages can be found in stdout.'
        )
Exemplo n.º 6
0
    def build(self) -> None:
        r"""
        This method can be used to build the generated code and install the resulting extension module into NEST.

        Raises
        ------
        GeneratedCodeBuildException
            If any kind of failure occurs during cmake configuration, build, or install.
        InvalidPathException
            If a failure occurs while trying to access the target path or the NEST installation path.
        """
        cmake_cmd = ["cmake"]
        target_path = FrontendConfiguration.get_target_path()
        install_path = FrontendConfiguration.get_install_path()
        if install_path is not None:
            add_libraries_to_sli(install_path)
        nest_path = self.get_option("nest_path")

        if not os.path.isdir(target_path):
            raise InvalidPathException('Target path (' + target_path +
                                       ') is not a directory!')

        if nest_path is None or (not os.path.isdir(nest_path)):
            raise InvalidPathException('NEST path (' + str(nest_path) +
                                       ') is not a directory!')

        install_prefix = ""
        if install_path:
            if not os.path.isabs(install_path):
                install_path = os.path.abspath(install_path)
            install_prefix = f"-DCMAKE_INSTALL_PREFIX={install_path}"

        nest_config_path = f"-Dwith-nest={os.path.join(nest_path, 'bin', 'nest-config')}"
        cmake_cmd = ['cmake', nest_config_path, install_prefix, '.']
        make_all_cmd = ['make', 'all']
        make_install_cmd = ['make', 'install']

        # remove CMakeCache.txt if exists
        cmake_cache = os.path.join(target_path, "CMakeCache.txt")
        if os.path.exists(cmake_cache):
            os.remove(cmake_cache)

        # check if we run on win
        if sys.platform.startswith('win'):
            shell = True
        else:
            shell = False

        # first call cmake with all the arguments
        try:
            result = subprocess.check_call(cmake_cmd,
                                           stderr=subprocess.STDOUT,
                                           shell=shell,
                                           cwd=str(os.path.join(target_path)))
        except subprocess.CalledProcessError as e:
            raise GeneratedCodeBuildException(
                'Error occurred during \'cmake\'! More detailed error messages can be found in stdout.'
            )

        # now execute make all
        try:
            subprocess.check_call(make_all_cmd,
                                  stderr=subprocess.STDOUT,
                                  shell=shell,
                                  cwd=str(os.path.join(target_path)))
        except subprocess.CalledProcessError as e:
            raise GeneratedCodeBuildException(
                'Error occurred during \'make all\'! More detailed error messages can be found in stdout.'
            )

        # finally execute make install
        try:
            subprocess.check_call(make_install_cmd,
                                  stderr=subprocess.STDOUT,
                                  shell=shell,
                                  cwd=str(os.path.join(target_path)))
        except subprocess.CalledProcessError as e:
            raise GeneratedCodeBuildException(
                'Error occurred during \'make install\'! More detailed error messages can be found in stdout.'
            )
Exemplo n.º 7
0
    def config(cls, _args=None):
        """
        Standard constructor.
        :param _args: a set of arguments as handed over to the frontend
        :type _args: list(str)
        """
        cls.argument_parser = argparse.ArgumentParser(
            description=
            'NESTML is a domain specific language that supports the specification of neuron models in a'
            ' precise and concise syntax, based on the syntax of Python. Model equations can either be '
            ' given as a simple string of mathematical notation or as an algorithm written in the built-in '
            ' procedural language. The equations are analyzed by NESTML to compute an exact solution'
            ' if possible or use an appropriate numeric solver otherwise.'
            ' Version 0.0.6, beta.')

        cls.argument_parser.add_argument('-path',
                                         type=str,
                                         nargs='+',
                                         help=help_path)
        cls.argument_parser.add_argument('-target',
                                         metavar='Target',
                                         type=str,
                                         nargs='?',
                                         help=help_target)
        cls.argument_parser.add_argument('-dry',
                                         action='store_true',
                                         help=help_dry)
        cls.argument_parser.add_argument('-logging_level',
                                         type=str,
                                         nargs='+',
                                         help=help_logging)
        cls.argument_parser.add_argument('-module_name',
                                         type=str,
                                         nargs='+',
                                         help=help_module)
        cls.argument_parser.add_argument('-store_log',
                                         action='store_true',
                                         help=help_log)
        cls.argument_parser.add_argument('-dev',
                                         action='store_true',
                                         help=help_dev)
        parsed_args = cls.argument_parser.parse_args(_args)
        cls.provided_path = parsed_args.path
        if cls.provided_path is None:
            # check if the mandatory path arg has been handed over, just terminate
            raise InvalidPathException('Invalid source path!')
        cls.paths_to_compilation_units = list()
        if parsed_args.path is None:
            raise InvalidPathException('Invalid source path!')
        elif os.path.isfile(parsed_args.path[0]):
            cls.paths_to_compilation_units.append(parsed_args.path[0])
        elif os.path.isdir(parsed_args.path[0]):
            for filename in os.listdir(parsed_args.path[0]):
                if filename.endswith(".nestml"):
                    cls.paths_to_compilation_units.append(
                        os.path.join(parsed_args.path[0], filename))
        else:
            cls.paths_to_compilation_units = parsed_args.path[0]
            raise InvalidPathException('Incorrect path provided' +
                                       parsed_args.path[0])
        # initialize the logger

        if parsed_args.logging_level is not None:
            cls.logging_level = parsed_args.logging_level
            Logger.init_logger(
                Logger.string_to_level(parsed_args.logging_level[0]))
        else:
            cls.logging_level = "ERROR"
            Logger.init_logger(Logger.string_to_level("ERROR"))
        # check if a dry run shall be preformed, i.e. without generating a target model
        cls.dry_run = parsed_args.dry
        # now update the target path
        cls.handle_target_path(parsed_args.target)
        # now adjust the name of the module, if it is a single file, then it is called just module
        if parsed_args.module_name is not None:
            cls.module_name = parsed_args.module_name[0]
        elif os.path.isfile(parsed_args.path[0]):
            cls.module_name = 'module'
        elif os.path.isdir(parsed_args.path[0]):
            cls.module_name = os.path.basename(
                os.path.normpath(parsed_args.path[0]))
        else:
            cls.module_name = 'module'
        cls.store_log = parsed_args.store_log
        cls.is_debug = parsed_args.dev
        return