def test_print_statement_with_variables(self):
        input_path = str(
            os.path.realpath(
                os.path.join(
                    os.path.dirname(__file__),
                    os.path.join('resources',
                                 'PrintStatementWithVariables.nestml'))))

        params = list()
        params.append('--input_path')
        params.append(input_path)
        params.append('--logging_level')
        params.append('INFO')
        params.append('--target_path')
        params.append(self.target_path)
        params.append('--dev')
        FrontendConfiguration.parse_config(params)
        compilation_unit = ModelParser.parse_model(input_path)

        nestCodeGenerator = NESTCodeGenerator()
        nestCodeGenerator.generate_code(compilation_unit.get_neuron_list())

        with open(
                str(
                    os.path.realpath(
                        os.path.join(
                            os.path.dirname(__file__),
                            os.path.join(os.pardir, 'target',
                                         'print_test_variables.cpp')))),
                'r') as reader:
            self.assertEqual(reader.read().count('std::cout'), 2)
Example #2
0
def to_nest(input_path,
            target_path=None,
            logging_level='ERROR',
            module_name=None,
            store_log=False,
            suffix="",
            dev=False):
    '''Translate NESTML files into their equivalent C++ code for the NEST simulator.

    Parameters
    ----------
    input_path : str
        Path to the NESTML file or to a folder containing NESTML files to convert to NEST code.
    target_path : str, optional (default: append "target" to `input_path`)
        Path to the generated C++ code and install files.
    logging_level : str, optional (default: 'ERROR')
        Sets which level of information should be displayed duing code generation (among 'ERROR', 'WARNING', 'INFO', or 'NO').
    module_name : str, optional (default: "nestmlmodule")
        Name of the module, which will be used to import the model in NEST via `nest.Install(module_name)`.
    store_log : bool, optional (default: False)
        Whether the log should be saved to file.
    suffix : str, optional (default: "")
        Suffix which will be appended to the model's name (internal use to avoid naming conflicts with existing NEST models).
    dev : bool, optional (default: False)
        Enable development mode: code generation is attempted even for models that contain errors, and extra information is rendered in the generated code.
    '''
    # if target_path is not None and not os.path.isabs(target_path):
    #    print('PyNestML: Please provide absolute target path!')
    #    return
    args = list()
    args.append(qualifier_input_path_arg)
    args.append(str(input_path))

    if target_path is not None:
        args.append(qualifier_target_path_arg)
        args.append(str(target_path))

    args.append(qualifier_target_arg)
    args.append(str("NEST"))
    args.append(qualifier_logging_level_arg)
    args.append(str(logging_level))

    if module_name is not None:
        args.append(qualifier_module_name_arg)
        args.append(str(module_name))

    if store_log:
        args.append(qualifier_store_log_arg)

    if suffix:
        args.append(qualifier_suffix_arg)
        args.append(suffix)

    if dev:
        args.append(qualifier_dev_arg)

    FrontendConfiguration.parse_config(args)
    if not process() == 0:
        raise Exception("Error(s) occurred while processing the model")
Example #3
0
def main(args):
    try:
        FrontendConfiguration.parse_config(args)
    except InvalidPathException:
        print('Not a valid path to model or directory: "%s"!' %
              FrontendConfiguration.get_path())
        return
    # after all argument have been collected, start the actual processing
    process()
Example #4
0
def main():
    """Returns the process exit code: 0 for success, > 0 for failure"""
    try:
        FrontendConfiguration.parse_config(sys.argv[1:])
    except InvalidPathException:
        print('Not a valid path to model or directory: "%s"!' % FrontendConfiguration.get_path())
        return 1
    # after all argument have been collected, start the actual processing
    return int(process())
Example #5
0
    def test_module_name_parsing_input_path_is_file(self):
        h, path = tempfile.mkstemp(prefix='nestml')
        basename = os.path.basename(os.path.normpath(path))

        params = list()
        params.append('--input_path')
        params.append(path)
        FrontendConfiguration.parse_config(params)
        assert FrontendConfiguration.module_name == 'nestmlmodule'
Example #6
0
    def test_module_name_parsing_input_path_is_wrong_dir(self):
        with pytest.raises(Exception):
            path = tempfile.mkdtemp(prefix='nestml-')

            params = list()
            params.append('--input_path')
            params.append(path)
            params.append('--logging_level')
            params.append('INFO')
            FrontendConfiguration.parse_config(params)
Example #7
0
    def test_module_name_parsing_wrong_module_name_specified(self):
        with pytest.raises(Exception):
            path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join('..', 'models'))))

            params = list()
            params.append('--input_path')
            params.append(path)
            params.append('--module_name')
            params.append('xyzzy')
            FrontendConfiguration.parse_config(params)
Example #8
0
    def test_module_name_parsing_right_module_name_specified(self):
        path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join('..', 'models'))))

        params = list()
        params.append('--input_path')
        params.append(path)
        params.append('--module_name')
        params.append('xyzzymodule')
        FrontendConfiguration.parse_config(params)

        assert FrontendConfiguration.module_name == 'xyzzymodule'
Example #9
0
    def test_module_name_parsing_input_path_is_dir(self):
        path = tempfile.mkdtemp(prefix='nestml')
        basename = os.path.basename(os.path.normpath(path))

        params = list()
        params.append('--input_path')
        params.append(path)
        params.append('--logging_level')
        params.append('INFO')
        FrontendConfiguration.parse_config(params)
        assert FrontendConfiguration.module_name == basename + 'module'
Example #10
0
def main():
    """Returns the process exit code: 0 for success, > 0 for failure"""
    try:
        FrontendConfiguration.parse_config(sys.argv[1:])
    except InvalidPathException:
        print('Not a valid path to model or directory: "%s"!' %
              FrontendConfiguration.get_path())
        return 1
    # the default Python recursion limit is 1000, which might not be enough in practice when running an AST visitor on a deep tree, e.g. containing an automatically generated expression
    sys.setrecursionlimit(10000)
    # after all argument have been collected, start the actual processing
    return int(process())
    def test_iaf_psc_alpha_with_codegen_opts(self):
        input_path = str(
            os.path.realpath(
                os.path.join(
                    os.path.dirname(__file__),
                    os.path.join(os.pardir, 'models', 'neurons',
                                 'iaf_psc_alpha.nestml'))))

        code_opts_path = str(
            os.path.realpath(
                os.path.join(os.path.dirname(__file__),
                             os.path.join('resources', 'code_options.json'))))
        codegen_opts = {
            "templates": {
                "path":
                "point_neuron",
                "model_templates": {
                    "neuron":
                    ['NeuronClass.cpp.jinja2', 'NeuronHeader.h.jinja2'],
                    "synapse": []
                },
                "module_templates": [
                    'setup/CMakeLists.txt.jinja2',
                    'setup/ModuleHeader.h.jinja2',
                    'setup/ModuleClass.cpp.jinja2'
                ]
            }
        }

        with open(code_opts_path, 'w+') as f:
            json.dump(codegen_opts, f)

        params = list()
        params.append('--input_path')
        params.append(input_path)
        params.append('--logging_level')
        params.append('INFO')
        params.append('--target_path')
        params.append(self.target_path)
        params.append('--dev')
        params.append('--codegen_opts')
        params.append(code_opts_path)
        FrontendConfiguration.parse_config(params)

        compilation_unit = ModelParser.parse_model(input_path)

        nestCodeGenerator = NESTCodeGenerator(codegen_opts)
        nestCodeGenerator.generate_code(compilation_unit.get_neuron_list(),
                                        list())
Example #12
0
    def test_input_path_handling_dir_one_file(self):
        path = tempfile.mkdtemp(prefix='nestml-')
        fd, fpath = tempfile.mkstemp(dir=path, suffix='.nestml')
        with open(fpath, 'w') as f:
            f.write('neuron foo:\nend\n')
            os.close(fd)

        params = list()
        params.append('--input_path')
        params.append(path)
        params.append('--logging_level')
        params.append('INFO')
        FrontendConfiguration.parse_config(params)

        assert len(FrontendConfiguration.paths_to_compilation_units) == 1
Example #13
0
def main() -> int:
    """
    Entry point for the command-line application.

    Returns
    -------
    The process exit code: 0 for success, > 0 for failure
    """
    try:
        FrontendConfiguration.parse_config(sys.argv[1:])
    except InvalidPathException as e:
        return 1
    # the default Python recursion limit is 1000, which might not be enough in practice when running an AST visitor on a deep tree, e.g. containing an automatically generated expression
    sys.setrecursionlimit(10000)
    # after all argument have been collected, start the actual processing
    return int(process())
Example #14
0
    def test_expressions(self):
        input_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join(
            'resources', 'ExpressionTypeTest.nestml'))))

        params = list()
        params.append('--input_path')
        params.append(input_path)
        params.append('--logging_level')
        params.append('INFO')
        params.append('--target_path')
        params.append(self.target_path)
        params.append('--dev')
        FrontendConfiguration.parse_config(params)
        compilation_unit = ModelParser.parse_model(input_path)

        nestCodeGenerator = NESTCodeGenerator()
        nestCodeGenerator.generate_code(compilation_unit.get_neuron_list())
Example #15
0
    def test_vector_code_generation(self):
        input_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join(
            'valid', 'VectorsDeclarationAndAssignment.nestml'))))

        params = list()
        params.append('--input_path')
        params.append(input_path)
        params.append('--logging_level')
        params.append('INFO')
        params.append('--target_path')
        params.append(self.target_path)
        params.append('--dev')
        FrontendConfiguration.parse_config(params)

        compilation_unit = ModelParser.parse_model(input_path)

        nestCodeGenerator = NESTCodeGenerator()
        nestCodeGenerator.generate_code(compilation_unit.get_neuron_list())
    def test_iaf_psc_delta(self):
        input_path = str(
            os.path.realpath(
                os.path.join(
                    os.path.dirname(__file__),
                    os.path.join(os.pardir, 'models', 'neurons',
                                 'iaf_psc_delta.nestml'))))

        params = list()
        params.append('--input_path')
        params.append(input_path)
        params.append('--logging_level')
        params.append('INFO')
        params.append('--target_path')
        params.append(self.target_path)
        params.append('--dev')
        FrontendConfiguration.parse_config(params)

        compilation_unit = ModelParser.parse_model(input_path)

        nestCodeGenerator = NESTCodeGenerator()
        nestCodeGenerator.generate_code(compilation_unit.get_neuron_list(),
                                        compilation_unit.get_synapse_list())
Example #17
0
    def test_iaf_cond_alpha_functional(self):
        input_path = str(
            os.path.realpath(
                os.path.join(
                    os.path.dirname(__file__),
                    os.path.join(os.pardir, 'models',
                                 'iaf_cond_alpha.nestml'))))

        params = list()
        params.append('--input_path')
        params.append(input_path)
        params.append('--logging_level')
        params.append('INFO')
        params.append('--target_path')
        params.append(self.target_path)
        params.append('--dev')
        FrontendConfiguration.parse_config(params)

        compilation_unit = ModelParser.parse_model(input_path)
        iaf_cond_alpha_functional = list()
        iaf_cond_alpha_functional.append(compilation_unit.get_neuron_list()[0])

        nestCodeGenerator = NESTCodeGenerator()
        nestCodeGenerator.generate_code(iaf_cond_alpha_functional, [])
Example #18
0
def generate_target(input_path: Union[str, Sequence[str]],
                    target_platform: str,
                    target_path=None,
                    install_path: str = None,
                    logging_level="ERROR",
                    module_name=None,
                    store_log=False,
                    suffix="",
                    dev=False,
                    codegen_opts: Optional[Mapping[str, Any]] = None):
    r"""Generate and build code for the given target platform.

    Parameters
    ----------
    input_path : str **or** Sequence[str]
        One or more input path(s). Each path is a NESTML file, or a directory containing NESTML files. Directories will be searched recursively for files matching ``*.nestml``.
    target_platform : str
        The name of the target platform to generate code for.
    target_path : str, optional (default: append "target" to `input_path`)
        Path to target directory where generated code will be written into. Default is ``target``, which will be created in the current working directory if it does not yet exist.
    logging_level : str, optional (default: "ERROR")
        Sets the logging level, i.e., which level of messages should be printed. Default is ERROR, available are: DEBUG, INFO, WARNING, ERROR, NO.
    module_name : str, optional (default: "nestmlmodule")
        Sets the name of the module which shall be generated. Default is the name of the directory containing the models. The name has to end in ``module``. Default is ``nestmlmodule``.
    store_log : bool, optional (default: False)
        Stores a log.txt containing all messages in JSON notation. Default is OFF.
    suffix : str, optional (default: "")
        A suffix string that will be appended to the name of all generated models.
    install_path
        Path to the directory where the generated code will be installed.
    dev : bool, optional (default: False)
        Enable development mode: code generation is attempted even for models that contain errors, and extra information is rendered in the generated code.
    codegen_opts : Optional[Mapping[str, Any]]
        A dictionary containing additional options for the target code generator.
    """
    args = list()
    args.append(qualifier_input_path_arg)
    if type(input_path) is str:
        args.append(str(input_path))
    else:
        for s in input_path:
            args.append(s)

    if target_path is not None:
        args.append(qualifier_target_path_arg)
        args.append(str(target_path))

    args.append(qualifier_target_platform_arg)
    args.append(target_platform)

    args.append(qualifier_logging_level_arg)
    args.append(str(logging_level))

    if module_name is not None:
        args.append(qualifier_module_name_arg)
        args.append(str(module_name))

    if store_log:
        args.append(qualifier_store_log_arg)

    if suffix:
        args.append(qualifier_suffix_arg)
        args.append(suffix)

    if install_path is not None:
        args.append(qualifier_install_path_arg)
        args.append(str(install_path))

    if dev:
        args.append(qualifier_dev_arg)

    FrontendConfiguration.parse_config(args)

    if codegen_opts:
        FrontendConfiguration.set_codegen_opts(codegen_opts)

    if not process() == 0:
        raise Exception("Error(s) occurred while processing the model")