示例#1
0
def test_templates():
    T1 = Templater('brian2.tests.test_templates.fake_package_1',
                   env_globals={
                       'f': lambda: 'F1',
                       'g': lambda: 'G1'
                   },
                   extension='.txt')
    T2 = T1.derive('brian2.tests.test_templates.fake_package_2',
                   env_globals={'f': lambda: 'F2'})
    ns = {}
    for i, T in enumerate([T1, T2], start=1):
        for c in ['A', 'B', 'C', 'D']:
            ns[c + str(i)] = getattr(T, c)('', '')
    # for k, v in ns.items():
    #     print k, v
    assert 'A1' in ns['A1']
    assert 'B1' in ns['A1']
    assert 'F1' in ns['A1']
    assert 'G1' in ns['A1']
    assert 'A2' in ns['A2']
    assert 'F2' in ns['A2']
    assert 'G1' in ns['A2']
    assert 'B1' not in ns['A2']
    assert 'B1' in ns['B1']
    assert 'B1' in ns['B2']
    assert 'C1' in ns['C1']
    assert 'D1' in ns['C1']
    assert 'C1' in ns['C2']
    assert 'D2' in ns['C2']
    assert 'D1' not in ns['C2']
    assert 'D1' in ns['D1']
    assert 'D2' in ns['D2']
示例#2
0
def test_templates():
    T1 = Templater('brian2.tests.test_templates.fake_package_1',
                   env_globals={'f': lambda: 'F1', 'g': lambda: 'G1'},
                   extension='.txt')
    T2 = T1.derive('brian2.tests.test_templates.fake_package_2',
                   env_globals={'f': lambda: 'F2'})
    ns = {}
    for i, T in enumerate([T1, T2], start=1):
        for c in ['A', 'B', 'C', 'D']:
            ns[c+str(i)] = getattr(T, c)('', '')
    # for k, v in ns.items():
    #     print k, v
    assert 'A1' in ns['A1']
    assert 'B1' in ns['A1']
    assert 'F1' in ns['A1']
    assert 'G1' in ns['A1']
    assert 'A2' in ns['A2']
    assert 'F2' in ns['A2']
    assert 'G1' in ns['A2']
    assert 'B1' not in ns['A2']
    assert 'B1' in ns['B1']
    assert 'B1' in ns['B2']
    assert 'C1' in ns['C1']
    assert 'D1' in ns['C1']
    assert 'C1' in ns['C2']
    assert 'D2' in ns['C2']
    assert 'D1' not in ns['C2']
    assert 'D1' in ns['D1']
    assert 'D2' in ns['D2']
示例#3
0
class CUDAStandaloneCodeObject(CPPStandaloneCodeObject):
    '''
    CUDA standalone code object
    
    The ``code`` should be a `~brian2.codegen.templates.MultiTemplate`
    object with two macros defined, ``main`` (for the main loop code) and
    ``support_code`` for any support code (e.g. function definitions).
    '''
    templater = Templater('brian2cuda',
                          '.cu',
                          env_globals={
                              'c_data_type': c_data_type,
                              'constant_or_scalar': constant_or_scalar
                          })
    generator_class = CUDACodeGenerator
    no_or_const_delay_mode = False
    serializing_form = "syn"
    runs_every_tick = True  #default True, set False in generate_main_source
    rand_calls = 0
    randn_calls = 0

    def __call__(self, **kwds):
        return self.run()

    def run(self):
        get_device().main_queue.append(('run_code_object', (self, )))
示例#4
0
class GeNNCodeObject(CodeObject):
    '''
    Class of code objects that generate GeNN "code snippets"
    '''
    templater = Templater('brian2genn', '.cpp',
                          env_globals={'c_data_type': c_data_type,
                                       'openmp_pragma': openmp_pragma,
                                       'constant_or_scalar': constant_or_scalar})
    generator_class = GeNNCodeGenerator
示例#5
0
class CUDAStandaloneCodeObject(CPPStandaloneCodeObject):
    '''
    CUDA standalone code object

    The ``code`` should be a `~brian2.codegen.templates.MultiTemplate`
    object with two macros defined, ``main`` (for the main loop code) and
    ``support_code`` for any support code (e.g. function definitions).
    '''
    templater = Templater('brian2cuda',
                          '.cu',
                          env_globals={
                              'c_data_type': c_data_type,
                              'constant_or_scalar': constant_or_scalar
                          })
    generator_class = CUDACodeGenerator

    def __init__(self, *args, **kwargs):
        super(CUDAStandaloneCodeObject, self).__init__(*args, **kwargs)
        # Whether this code object runs on a clock or only once. Default is True, set
        # False in `CUDAStandaloneDevice.generate_main_source()`
        self.runs_every_tick = True
        # Dictionary collectin the number of RNG function calls in this code object.
        # Keys are: "rand", "randn", "poisson-<idx>" with one <idx> for each `poisson`
        # with different (scalar) lambda
        self.rng_calls = defaultdict(int)
        # {name: lambda} dictionary for all poisson functions with scalar lambda
        # (these random numbers will be generated using the curand host side API)
        self.poisson_lamdas = defaultdict(float)
        # Whether this codeobject uses curand device API (for binomial functions or
        # poisson with vectorized lambda) and needs curand states
        self.needs_curand_states = False

    def __call__(self, **kwds):
        return self.run()

    def compile_block(self, block):
        pass  # Compilation will be handled in device

    def run_block(self, block):
        if block == 'run':
            get_device().main_queue.append((block + '_code_object', (self, )))
        else:
            # Check the C++ code whether there is anything to run
            cu_code = getattr(self.code, block + '_cu_file')
            if len(cu_code) and 'EMPTY_CODE_BLOCK' not in cu_code:
                get_device().main_queue.append(
                    (block + '_code_object', (self, )))
                self.before_after_blocks.append(block)
示例#6
0
class CPPStandaloneCodeObject(CodeObject):
    '''
    C++ standalone code object
    
    The ``code`` should be a `~brian2.codegen.templates.MultiTemplate`
    object with two macros defined, ``main`` (for the main loop code) and
    ``support_code`` for any support code (e.g. function definitions).
    '''
    templater = Templater('brian2.devices.cpp_standalone',
                          env_globals={'c_data_type': c_data_type})
    generator_class = CPPCodeGenerator

    def __call__(self, **kwds):
        return self.run()

    def run(self):
        get_device().main_queue.append(('run_code_object', (self, )))
示例#7
0
class CPPStandaloneCodeObject(CodeObject):
    '''
    C++ standalone code object
    
    The ``code`` should be a `~brian2.codegen.templates.MultiTemplate`
    object with two macros defined, ``main`` (for the main loop code) and
    ``support_code`` for any support code (e.g. function definitions).
    '''
    templater = Templater('brian2.devices.cpp_standalone',
                          '.cpp',
                          env_globals={
                              'c_data_type': c_data_type,
                              'openmp_pragma': openmp_pragma,
                              'constant_or_scalar': constant_or_scalar,
                              'prefs': prefs,
                              'zip': zip
                          })
    generator_class = CPPCodeGenerator

    def __init__(self, *args, **kwds):
        super(CPPStandaloneCodeObject, self).__init__(*args, **kwds)
        #: Store whether this code object defines before/after blocks
        self.before_after_blocks = []

    def __call__(self, **kwds):
        return self.run()

    def compile_block(self, block):
        pass  # Compilation will be handled in device

    def run_block(self, block):
        if block == 'run':
            get_device().main_queue.append((block + '_code_object', (self, )))
        else:
            # Check the C++ code whether there is anything to run
            cpp_code = getattr(self.code, block + '_cpp_file')
            if len(cpp_code) and 'EMPTY_CODE_BLOCK' not in cpp_code:
                get_device().main_queue.append(
                    (block + '_code_object', (self, )))
                self.before_after_blocks.append(block)
示例#8
0
class GeNNCodeObject(CodeObject):
    '''
    Class of code objects that generate GeNN "code snippets"
    '''
    templater = Templater('brian2genn', '.cpp',
                          env_globals={'c_data_type': c_data_type,
                                       'openmp_pragma': openmp_pragma,
                                       'constant_or_scalar': constant_or_scalar,
                                       'zip': zip})
    generator_class = GeNNCodeGenerator

    # Overwrite Brian2 methods, we do not need to compile/run anything here
    def compile(self):
        pass

    def before_run(self):
        pass

    def run(self):
        pass

    def after_run(self):
        pass