예제 #1
0
            def _get_kernel_gens():
                # two kernels (one for each generator)
                instructions0 = ("""
                        {arg} = 1
                    """)
                instructions1 = ("""
                        {arg} = 2
                    """)

                # create mapstore
                domain = arc.creator('domain',
                                     arc.kint_type, (10, ),
                                     'C',
                                     initializer=np.arange(
                                         10, dtype=arc.kint_type))
                mapstore = arc.MapStore(opts, domain, None)
                # create global arg
                arg = arc.creator('arg', np.float64,
                                  (arc.problem_size.name, 10), opts.order)
                # create array / array string
                arg_lp, arg_str = mapstore.apply_maps(arg, 'j', 'i')

                # create kernel infos
                knl0 = knl_info('knl0',
                                instructions0.format(arg=arg_str),
                                mapstore,
                                kernel_data=[arg_lp, arc.work_size])
                knl1 = knl_info('knl1',
                                instructions1.format(arg=arg_str),
                                mapstore,
                                kernel_data=[arg_lp, arc.work_size])
                # create generators
                gen0 = make_kernel_generator(opts,
                                             KernelType.dummy, [knl0],
                                             type('', (object, ), {'jac': ''}),
                                             name=knl0.name,
                                             output_arrays=['arg'])
                gen1 = make_kernel_generator(opts,
                                             KernelType.dummy, [knl0, knl1],
                                             type('', (object, ), {'jac': ''}),
                                             depends_on=[gen0],
                                             name=knl1.name,
                                             output_arrays=['arg'])
                return gen0, gen1
예제 #2
0
    def test_lockstep_driver(self):
        # get rate info
        rate_info = determine_jac_inds(self.store.reacs, self.store.specs,
                                       RateSpecialization.fixed)
        mod_test = get_run_source()

        for kind, loopy_opts in OptionLoopWrapper.from_get_oploop(
                self, do_ratespec=False, langs=get_test_langs(),
                do_vector=True, yield_index=True):

            # make namestore
            namestore = arc.NameStore(loopy_opts, rate_info)

            # kernel 1 - need the jacobian reset kernel
            reset = reset_arrays(loopy_opts, namestore)
            # kernel 2 - incrementer
            # make mapstore, arrays and kernel info
            mapstore = arc.MapStore(loopy_opts, namestore.phi_inds, None)

            # use arrays of 2 & 3 dimensions to test the driver's copying
            base_phi_shape = namestore.n_arr.shape
            P_lp, P_str = mapstore.apply_maps(namestore.P_arr,
                                              arc.global_ind)
            phi_lp, phi_str = mapstore.apply_maps(namestore.n_arr,
                                                  arc.global_ind,
                                                  arc.var_name)
            inputs = [P_lp.name, phi_lp.name]
            base_jac_shape = namestore.jac.shape
            jac_lp, jac_str = mapstore.apply_maps(namestore.jac,
                                                  arc.global_ind,
                                                  arc.var_name,
                                                  arc.var_name)
            outputs = [jac_lp.name]
            kernel_data = [P_lp, phi_lp, jac_lp]
            kernel_data.extend(arc.initial_condition_dimension_vars(
                loopy_opts, None))
            instructions = Template("""
                ${phi_str} = ${phi_str} + ${P_str} {id=0, dep=*}
                ${jac_str} = ${jac_str} + ${phi_str} {id=1, dep=0, nosync=0}
            """).safe_substitute(**locals())

            # handle atomicity
            can_vec, vec_spec = ic.get_deep_specializer(
                loopy_opts, atomic_ids=['1'])
            barriers = []
            if loopy_opts.depth:
                # need a barrier between the reset & the kernel
                barriers = [(0, 1, 'global')]

            inner_kernel = k_gen.knl_info(
                name='inner',
                instructions=instructions,
                mapstore=mapstore,
                var_name=arc.var_name,
                kernel_data=kernel_data,
                silenced_warnings=['write_race(0)', 'write_race(1)'],
                can_vectorize=can_vec,
                vectorization_specializer=vec_spec)

            # put it in a generator
            generator = k_gen.make_kernel_generator(
                loopy_opts, kernel_type=KernelType.dummy,
                name='inner_kernel', kernels=[reset, inner_kernel],
                namestore=namestore,
                input_arrays=inputs[:],
                output_arrays=outputs[:],
                is_validation=True,
                driver_type=DriverType.lockstep,
                barriers=barriers)

            # use a "weird" (non-evenly divisibly by vector width) test-size to
            # properly test the copy-in / copy-out
            test_size = self.store.test_size - 37
            if test_size <= 0:
                test_size = self.store.test_size - 1
                assert test_size > 0
            # and make
            with temporary_build_dirs() as (build, obj, lib):

                numpy_arrays = []

                def __save(shape, name, zero=False):
                    data = np.zeros(shape)
                    if not zero:
                        # make it a simple range
                        data.flat[:] = np.arange(np.prod(shape))
                    # save
                    myname = pjoin(lib, name + '.npy')
                    # need to split inputs / answer
                    np.save(myname, data.flatten('K'))
                    numpy_arrays.append(data.flatten('K'))

                # write 'data'
                import loopy as lp
                for arr in kernel_data:
                    if not isinstance(arr, lp.ValueArg):
                        __save((test_size,) + arr.shape[1:], arr.name,
                               arr.name in outputs)

                # and a parameter
                param = np.zeros((test_size,))
                param[:] = np.arange(test_size)

                # build code
                generator.generate(build,
                                   data_order=loopy_opts.order,
                                   data_filename='data.bin',
                                   for_validation=True)

                # write header
                write_aux(build, loopy_opts, self.store.specs, self.store.reacs)

                # generate wrapper
                pywrap(loopy_opts.lang, build,
                       obj_dir=obj, out_dir=lib,
                       ktype=KernelType.dummy,
                       file_base=generator.name,
                       additional_inputs=inputs[:],
                       additional_outputs=outputs[:])

                # and calling script
                test = pjoin(lib, 'test.py')

                inputs = utils.stringify_args(
                    [pjoin(lib, inp + '.npy') for inp in inputs], use_quotes=True)
                str_outputs = utils.stringify_args(
                    [pjoin(lib, inp + '.npy') for inp in outputs], use_quotes=True)

                num_threads = _get_test_input(
                    'num_threads', psutil.cpu_count(logical=False))
                with open(test, 'w') as file:
                    file.write(mod_test.safe_substitute(
                        package='pyjac_{lang}'.format(
                            lang=utils.package_lang[loopy_opts.lang]),
                        input_args=inputs,
                        test_arrays=str_outputs,
                        output_files=str_outputs,
                        looser_tols='[]',
                        loose_rtol=0,
                        loose_atol=0,
                        rtol=0,
                        atol=0,
                        non_array_args='{}, {}'.format(
                            test_size, num_threads),
                        kernel_name=generator.name.title(),))

                try:
                    utils.run_with_our_python([test])
                except subprocess.CalledProcessError:
                    logger = logging.getLogger(__name__)
                    logger.debug(utils.stringify_args(vars(loopy_opts), kwd=True))
                    assert False, 'lockstep_driver error'

                # calculate answers
                ns = base_jac_shape[1]
                # pressure is added to phi
                phi = numpy_arrays[1].reshape((test_size, ns),
                                              order=loopy_opts.order)
                p_arr = numpy_arrays[0]
                phi = phi + p_arr[:, np.newaxis]
                jac = numpy_arrays[2].reshape((test_size, ns, ns),
                                              order=loopy_opts.order)
                # and the diagonal of the jacobian has the updated pressure added
                jac[:, range(ns), range(ns)] += phi[:, range(ns)]
                # and read in outputs
                test = np.load(pjoin(lib, outputs[0] + '.npy')).reshape(
                    jac.shape, order=loopy_opts.order)
                assert np.array_equal(test, jac)
예제 #3
0
def test_unsimdable():
    from loopy.kernel.array import (VectorArrayDimTag)
    inds = ('j', 'i')
    test_size = 16
    for opt in opts_loop(is_simd=True,
                         skip_test=lambda state:
                         state['depth'] and state['is_simd']):
        # make a kernel via the mapstore / usual methods
        base = creator('base', dtype=kint_type, shape=(10,), order=opt.order,
                       initializer=np.arange(10, dtype=kint_type))
        mstore = MapStore(opt, base, 8192)

        def __create_var(name, size=(test_size, 10)):
            return creator(name, kint_type, size, opt.order)

        # now create different arrays:

        # one that will cause a map transform
        mapt = creator('map', dtype=kint_type, shape=(10,), order=opt.order,
                       initializer=np.array(list(range(0, 3)) + list(range(4, 11)),
                       kint_type))
        mapv = __create_var('mapv')
        mstore.check_and_add_transform(mapv, mapt)

        # one that is only an affine transform
        affinet = creator('affine', dtype=kint_type, shape=(10,), order=opt.order,
                          initializer=np.arange(2, 12, dtype=kint_type))
        affinev = __create_var('affinev', (test_size, 12))
        mstore.check_and_add_transform(affinev, affinet)

        # and one that is a child of the affine transform
        affinet2 = creator('affine2', dtype=kint_type, shape=(10,), order=opt.order,
                           initializer=np.arange(4, 14, dtype=kint_type))
        mstore.check_and_add_transform(affinet2, affinet)
        # and add a child to it
        affinev2 = __create_var('affinev2', (test_size, 14))
        mstore.check_and_add_transform(affinev2, affinet2)

        # and finally, a child of the map transform
        mapt2 = creator('map2', dtype=kint_type, shape=(10,), order=opt.order,
                        initializer=np.array(list(range(0, 2)) + list(range(3, 11)),
                        kint_type))
        mstore.check_and_add_transform(mapt2, mapt)
        # and a child
        mapv2 = __create_var('mapv2')
        mstore.check_and_add_transform(mapv2, mapt2)

        # now create an kernel info
        affine_lp, affine_str = mstore.apply_maps(affinev, *inds)
        affine2_lp, affine2_str = mstore.apply_maps(affinev2, *inds)
        map_lp, map_str = mstore.apply_maps(mapv, *inds)
        map2_lp, map2_str = mstore.apply_maps(mapv2, *inds)

        instructions = Template(remove_common_indentation("""
        ${affine_str} = 0
        ${affine2_str} = 0
        ${map_str} = 0
        ${map2_str} = 0
        """)).safe_substitute(**locals())

        info = knl_info('test', instructions, mstore, kernel_data=[
            affine_lp, affine2_lp, map_lp, map2_lp])

        # create a dummy kgen
        kgen = make_kernel_generator(opt, KernelType.dummy, [info],
                                     type('namestore', (object,), {'jac': 0}),
                                     test_size=test_size, name='test')

        # make kernels
        kgen._make_kernels()

        # and call simdable
        cant_simd = _unSIMDable_arrays(kgen.kernels[0], opt, mstore,
                                       warn=False)

        if opt.depth:
            assert sorted(cant_simd) == [mapt2.name, map_lp.name, map2_lp.name]
        else:
            assert cant_simd == []

        # make sure we can generate code
        lp.generate_code_v2(kgen.kernels[0]).device_code()

        if not kgen.array_split.vector_width:
            continue

        # check that we've vectorized all arrays
        assert all(len(arr.shape) == 3 for arr in kgen.kernels[0].args
                   if isinstance(arr, lp.ArrayArg))

        # get the split axis
        _, _, vec_axis, _ = kgen.array_split.split_shape(affine_lp)

        assert all(isinstance(arr.dim_tags[vec_axis], VectorArrayDimTag)
                   for arr in kgen.kernels[0].args if arr.name not in cant_simd
                   and isinstance(arr, lp.ArrayArg))
예제 #4
0
    def test_read_initial_conditions(self):
        setup = test_utils.get_read_ics_source()
        wrapper = OptionLoopWrapper.from_get_oploop(self, do_conp=True)
        for opts in wrapper:
            with temporary_build_dirs() as (build_dir, obj_dir, lib_dir):
                conp = wrapper.state['conp']

                # make a dummy generator
                insns = ("""
                        {spec} = {param} {{id=0}}
                    """)
                domain = arc.creator('domain',
                                     arc.kint_type, (10, ),
                                     'C',
                                     initializer=np.arange(
                                         10, dtype=arc.kint_type))
                mapstore = arc.MapStore(opts, domain, None)
                # create global args
                param = arc.creator(arc.pressure_array, np.float64,
                                    (arc.problem_size.name, 10), opts.order)
                spec = arc.creator(arc.state_vector, np.float64,
                                   (arc.problem_size.name, 10), opts.order)
                namestore = type('', (object, ), {'jac': ''})
                # create array / array strings
                param_lp, param_str = mapstore.apply_maps(param, 'j', 'i')
                spec_lp, spec_str = mapstore.apply_maps(spec, 'j', 'i')

                # create kernel infos
                info = knl_info('spec_eval',
                                insns.format(param=param_str, spec=spec_str),
                                mapstore,
                                kernel_data=[spec_lp, param_lp, arc.work_size],
                                silenced_warnings=['write_race(0)'])
                # create generators
                kgen = make_kernel_generator(
                    opts,
                    KernelType.dummy, [info],
                    namestore,
                    input_arrays=[param.name, spec.name],
                    output_arrays=[spec.name],
                    name='ric_tester')
                # make kernels
                kgen._make_kernels()
                # and generate RIC
                _, record, _ = kgen._generate_wrapping_kernel(build_dir)
                kgen._generate_common(build_dir, record)
                ric = os.path.join(
                    build_dir,
                    'read_initial_conditions' + utils.file_ext[opts.lang])

                # write header
                write_aux(build_dir, opts, self.store.specs, self.store.reacs)
                with open(os.path.join(build_dir, 'setup.py'), 'w') as file:
                    file.write(
                        setup.safe_substitute(buildpath=build_dir,
                                              obj_dir=obj_dir))

                # and compile
                from pyjac.libgen import compile, get_toolchain
                toolchain = get_toolchain(opts.lang)
                compile(opts.lang, toolchain, [ric], obj_dir=obj_dir)

                # write wrapper
                self.__write_with_subs('read_ic_wrapper.pyx',
                                       os.path.join(self.store.script_dir,
                                                    'test_utils'),
                                       build_dir,
                                       header_ext=utils.header_ext[opts.lang])
                # setup
                utils.run_with_our_python([
                    os.path.join(build_dir, 'setup.py'), 'build_ext',
                    '--build-lib', lib_dir
                ])

                infile = os.path.join(self.store.script_dir, 'test_utils',
                                      'ric_tester.py.in')
                outfile = os.path.join(lib_dir, 'ric_tester.py')
                # cogify
                try:
                    Cog().callableMain([
                        'cogapp', '-e', '-d', '-Dconp={}'.format(conp), '-o',
                        outfile, infile
                    ])
                except Exception:
                    import logging
                    logger = logging.getLogger(__name__)
                    logger.error('Error generating initial conditions reader:'
                                 ' {}'.format(outfile))
                    raise

                # save phi, param in correct order
                phi = (self.store.phi_cp if conp else self.store.phi_cv)
                savephi = phi.flatten(opts.order)
                param = self.store.P if conp else self.store.V
                savephi.tofile(os.path.join(lib_dir, 'phi_test.npy'))
                param.tofile(os.path.join(lib_dir, 'param_test.npy'))

                # save bin file
                out_file = np.concatenate(
                    (
                        np.reshape(phi[:, 0], (-1, 1)),  # temperature
                        np.reshape(param, (-1, 1)),  # param
                        phi[:, 1:]),
                    axis=1  # species
                )
                out_file = out_file.flatten('K')
                with open(os.path.join(lib_dir, 'data.bin'), 'wb') as file:
                    out_file.tofile(file)

                # and run
                utils.run_with_our_python(
                    [outfile, opts.order,
                     str(self.store.test_size)])
예제 #5
0
def mass_to_mole_factions(loopy_opts, namestore, conp=True, test_size=None):
    """Converts input state vector from mass fractions to mole fractions and state
       variables depending on constant pressure vs constant volue assumption

    Parameters
    ----------
    loopy_opts : `loopy_options` object
        A object containing all the loopy options to execute
    namestore : :class:`array_creator.NameStore`
        The namestore / creator for this method
    conp : bool
        If true, generate equations using constant pressure assumption
        If false, use constant volume equations
    test_size : int
        If not none, this kernel is being used for testing.
        Hence we need to size the arrays accordingly

    Notes
    -----
    Assumes that this is being called at input only!
    This allows us to make the (generally) unsafe assumption that the mole factions
    are _equivalent_ to the moles, as the total number of moles will adjust to
    satisfy the ideal gas relation.


    Returns
    -------
    knl_list : list of :class:`knl_info`
        The generated infos for feeding into the kernel generator for both
        equation types
    """

    # first kernel, determine molecular weight
    mapstore = arc.MapStore(loopy_opts, namestore.num_specs_no_ns, test_size)

    # first, create all arrays
    kernel_data = []

    # add problem size
    kernel_data.extend(arc.initial_condition_dimension_vars(loopy_opts, test_size))

    # need "Yi" and molecular weight / factor arrays

    # add / apply maps
    mapstore.check_and_add_transform(namestore.n_arr,
                                     namestore.phi_spec_inds,
                                     force_inline=True)
    mapstore.check_and_add_transform(namestore.mw_post_arr,
                                     namestore.num_specs_no_ns,
                                     force_inline=True)

    Yi_arr, Yi_str = mapstore.apply_maps(namestore.n_arr, *default_inds)
    mw_inv_arr, mw_inv_str = mapstore.apply_maps(namestore.mw_inv, var_name)
    mw_work_arr, mw_work_str = mapstore.apply_maps(namestore.mw_work, global_ind)

    # add arrays
    kernel_data.extend([Yi_arr, mw_inv_arr, mw_work_arr])

    # initialize molecular weight
    pre_instructions = Template(
        """
            ${mw_work_str} = W_ns_inv {id=init}
            <> work = 0 {id=init_work}
        """
    ).safe_substitute(**locals())

    instructions = Template(
        """
            work = work + (${mw_inv_str} - W_ns_inv) * ${Yi_str} \
                {id=update, dep=init*}
        """).safe_substitute(**locals())

    barrier = ic.get_barrier(loopy_opts, local_memory=False,
                             id='break', dep='update')
    post_instructions = Template(
        """
        ${barrier}
        ${mw_work_str} = (${mw_work_str} + work) {id=final, dep=break, nosync=init}
        """).substitute(**locals())

    can_vectorize, vec_spec = ic.get_deep_specializer(
        loopy_opts, atomic_ids=['final'], init_ids=['init'])

    mw_kernel = k_gen.knl_info(name='molecular_weight_inverse',
                               pre_instructions=[pre_instructions],
                               instructions=instructions,
                               post_instructions=[post_instructions],
                               mapstore=mapstore,
                               var_name=var_name,
                               kernel_data=kernel_data,
                               can_vectorize=can_vectorize,
                               vectorization_specializer=vec_spec,
                               parameters={'W_ns_inv': 1. / np.float64(
                                                namestore.mw_arr[-1])},
                               silenced_warnings=['write_race(final)',
                                                  'write_race(init)'])

    # now convert to moles
    mapstore = arc.MapStore(loopy_opts, namestore.num_specs_no_ns, test_size)

    # first, create all arrays
    kernel_data = []

    # add problem size
    kernel_data.extend(arc.initial_condition_dimension_vars(loopy_opts, test_size))

    # need input "Yi", molecular weight, and moles array

    # add / apply maps
    mapstore.check_and_add_transform(namestore.n_arr,
                                     namestore.phi_spec_inds,
                                     force_inline=True)

    n_arr, n_str = mapstore.apply_maps(namestore.n_arr, *default_inds)
    mw_work_arr, mw_work_str = mapstore.apply_maps(namestore.mw_work, global_ind)
    mw_inv_arr, mw_inv_str = mapstore.apply_maps(namestore.mw_inv, var_name)

    # add arrays
    kernel_data.extend([n_arr, mw_inv_arr, mw_work_arr])

    pre_instructions = Template(
        '<> mw = 1 / ${mw_work_str} {id=init}').safe_substitute(**locals())
    instructions = Template(
        """
            ${n_str} = ${n_str} * ${mw_inv_str} * mw {dep=init}
        """).safe_substitute(**locals())

    can_vectorize, vec_spec = ic.get_deep_specializer(loopy_opts)
    mf_kernel = k_gen.knl_info(name='mole_fraction',
                               pre_instructions=[pre_instructions],
                               instructions=instructions,
                               mapstore=mapstore,
                               var_name=var_name,
                               kernel_data=kernel_data,
                               can_vectorize=can_vectorize,
                               vectorization_specializer=vec_spec)

    return [mw_kernel, mf_kernel]
예제 #6
0
    def test_read_initial_condition_generator(self):
        oploop = OptionLoopWrapper.from_get_oploop(self,
                                                   do_conp=False,
                                                   do_vector=True,
                                                   do_sparse=False)
        for opts in oploop:
            # two kernels (one for each generator)
            spec_insns = ("""
                    {spec} = {param} {{id=0}}
                """)
            param_insns = ("""
                    {param} = 1 {{id=1}}
                """)
            # create mapstore
            domain = arc.creator('domain',
                                 arc.kint_type, (10, ),
                                 'C',
                                 initializer=np.arange(10,
                                                       dtype=arc.kint_type))
            mapstore = arc.MapStore(opts, domain, None)
            # create global args
            param = arc.creator(arc.pressure_array, np.float64,
                                (arc.problem_size.name, 10), opts.order)
            spec = arc.creator('longanddistinct', np.float64,
                               (arc.problem_size.name, 10), opts.order)
            namestore = type('', (object, ), {
                'param': param,
                'spec': spec,
                'jac': ''
            })
            # create array / array strings
            param_lp, param_str = mapstore.apply_maps(param, 'j', 'i')
            spec_lp, spec_str = mapstore.apply_maps(spec, 'j', 'i')

            # create kernel infos
            spec_info = knl_info(
                'spec_eval',
                spec_insns.format(param=param_str, spec=spec_str),
                mapstore,
                kernel_data=[spec_lp, param_lp, arc.work_size],
                silenced_warnings=['write_race(0)'])
            param_info = knl_info('param_eval',
                                  param_insns.format(param=param_str),
                                  mapstore,
                                  kernel_data=[param_lp, arc.work_size],
                                  silenced_warnings=['write_race(1)'])
            # create generators
            param_gen = make_kernel_generator(opts,
                                              KernelType.chem_utils,
                                              [param_info],
                                              namestore,
                                              output_arrays=[param.name])
            spec_gen = make_kernel_generator(
                opts,
                KernelType.species_rates, [spec_info],
                namestore,
                depends_on=[param_gen],
                input_arrays=[spec.name, param.name],
                output_arrays=[spec.name])

            # get the record
            with temporary_directory() as tdir:
                spec_gen._make_kernels()
                _, record, _ = spec_gen._generate_wrapping_kernel(tdir)

                # and call the read IC gen
                spec_gen._generate_common(tdir, record)

                # read in header
                with open(
                        os.path.join(
                            tdir,
                            'read_initial_conditions' + header_ext[opts.lang]),
                        'r') as file:
                    file = file.read()
                assert 'double* longanddistinct' in file

                # read in source
                with open(
                        os.path.join(
                            tdir,
                            'read_initial_conditions' + file_ext[opts.lang]),
                        'r') as file:
                    file = file.read()
                assert 'double* longanddistinct' in file
예제 #7
0
    def __get_call_kernel_generator(self, opts, spec_name='spec'):
        # create some test kernels

        # first, make a (potentially) host constant
        const = np.arange(10, dtype=arc.kint_type)
        const = lp.TemporaryVariable('const',
                                     shape=const.shape,
                                     initializer=const,
                                     read_only=True,
                                     address_space=scopes.GLOBAL)

        # and finally two kernels (one for each generator)
        # kernel 0 contains the non-shared temporary
        jac_insns = ("""
                {jac} = {jac} + {spec} {{id=0}}
            """)
        spec_insns = ("""
                {spec} = {spec} + {chem} {{id=1}}
            """)
        chem_insns = ("""
                {chem} = const[i] {{id=2}}
            """)

        # create mapstore
        domain = arc.creator('domain',
                             arc.kint_type, (10, ),
                             'C',
                             initializer=np.arange(10, dtype=arc.kint_type))
        mapstore = arc.MapStore(opts, domain, None)
        # create global args
        jac = arc.creator('jac', np.float64, (arc.problem_size.name, 10),
                          opts.order)
        spec = arc.creator(spec_name, np.float64, (arc.problem_size.name, 10),
                           opts.order)
        chem = arc.creator('chem', np.float64, (arc.problem_size.name, 10),
                           opts.order)
        namestore = type('', (object, ), {
            'jac': jac,
            'spec': spec,
            'chem': chem
        })
        # create array / array strings
        jac_lp, jac_str = mapstore.apply_maps(jac, 'j', 'i')
        spec_lp, spec_str = mapstore.apply_maps(spec, 'j', 'i')
        chem_lp, chem_str = mapstore.apply_maps(chem, 'j', 'i')

        # create kernel infos
        jac_info = knl_info('jac_eval',
                            jac_insns.format(jac=jac_str, spec=spec_str),
                            mapstore,
                            kernel_data=[jac_lp, spec_lp, arc.work_size],
                            silenced_warnings=['write_race(0)'])
        spec_info = knl_info('spec_eval',
                             spec_insns.format(spec=spec_str, chem=chem_str),
                             mapstore,
                             kernel_data=[spec_lp, chem_lp, arc.work_size],
                             silenced_warnings=['write_race(1)'])
        chem_info = knl_info('chem_eval',
                             chem_insns.format(chem=chem_str),
                             mapstore,
                             kernel_data=[chem_lp, const, arc.work_size],
                             silenced_warnings=['write_race(2)'])

        # create generators
        chem_gen = make_kernel_generator(opts,
                                         KernelType.chem_utils, [chem_info],
                                         namestore,
                                         output_arrays=['chem'])
        spec_gen = make_kernel_generator(opts,
                                         KernelType.species_rates, [spec_info],
                                         namestore,
                                         depends_on=[chem_gen],
                                         input_arrays=['chem'],
                                         output_arrays=[spec_name])
        jac_gen = make_kernel_generator(opts,
                                        KernelType.jacobian, [jac_info],
                                        namestore,
                                        depends_on=[spec_gen],
                                        input_arrays=[spec_name],
                                        output_arrays=['jac'])

        return jac_gen
예제 #8
0
    def test_deduplication(self):
        oploop = OptionLoopWrapper.from_get_oploop(self,
                                                   do_conp=False,
                                                   do_vector=False,
                                                   do_sparse=False)
        # create some test kernels

        # first, make a shared temporary
        shared = np.arange(10, dtype=arc.kint_type)
        shared = lp.TemporaryVariable('shared',
                                      shape=shared.shape,
                                      initializer=shared,
                                      read_only=True,
                                      address_space=scopes.GLOBAL)

        # test for issue where inits defined in the top kernel were accidentally
        # removed
        nonshared_top = np.arange(10, dtype=arc.kint_type)
        nonshared_top = lp.TemporaryVariable('nonshared_top',
                                             shape=nonshared_top.shape,
                                             initializer=nonshared_top,
                                             read_only=True,
                                             address_space=scopes.GLOBAL)

        # and a non-shared temporary
        nonshared = np.arange(10, dtype=arc.kint_type)
        nonshared = lp.TemporaryVariable('nonshared',
                                         shape=nonshared.shape,
                                         initializer=nonshared,
                                         read_only=True,
                                         address_space=scopes.GLOBAL)

        # and a preamble generator function -> fastpowi_PreambleGen
        pre = [dummy_preamble()]

        # and finally two kernels (one for each generator)
        # kernel 0 contains the non-shared temporary
        instructions0 = ("""
                {arg} = shared[i] + dummy(nonshared[i], 1)
            """)
        instructions1 = ("""
                {arg} = {arg} + shared[i] + dummy(nonshared_top[i], 1)
            """)

        for opts in oploop:
            # create mapstore
            domain = arc.creator('domain',
                                 arc.kint_type, (10, ),
                                 'C',
                                 initializer=np.arange(10,
                                                       dtype=arc.kint_type))
            mapstore = arc.MapStore(opts, domain, None)
            # create global arg
            arg = arc.creator('arg', np.float64, (arc.problem_size.name, 10),
                              opts.order)
            # create array / array string
            arg_lp, arg_str = mapstore.apply_maps(arg, 'j', 'i')

            # create kernel infos
            knl0 = knl_info(
                'knl0',
                instructions0.format(arg=arg_str),
                mapstore,
                kernel_data=[arg_lp, shared, nonshared, arc.work_size],
                manglers=pre)
            knl1 = knl_info(
                'knl1',
                instructions1.format(arg=arg_str),
                mapstore,
                kernel_data=[arg_lp, shared, nonshared_top, arc.work_size],
                manglers=pre)
            # create generators
            gen0 = make_kernel_generator(opts,
                                         KernelType.dummy, [knl0],
                                         type('', (object, ), {'jac': ''}),
                                         input_arrays=['arg'],
                                         output_arrays=['arg'],
                                         name=knl0.name)
            gen1 = make_kernel_generator(opts,
                                         KernelType.dummy, [knl1],
                                         type('', (object, ), {'jac': ''}),
                                         depends_on=[gen0],
                                         input_arrays=['arg'],
                                         output_arrays=['arg'],
                                         name=knl1.name)

            def __get_result(gen, record=None):
                # make kernels
                gen._make_kernels()

                if not record:
                    # process the arguements
                    record, _ = gen._process_args()

                    # test that process memory works
                    record, mem_limits = gen._process_memory(record)

                # and generate working buffers
                recordnew, result = gen._compress_to_working_buffer(record)

                result = gen._merge_kernels(record, result)

                return result, record

            result1, record = __get_result(gen1)
            result2, _ = __get_result(gen0)
            results = [result1, result2]

            # and de-duplicate
            results = gen1._deduplicate(record, results)

            # check inits & preambles
            inits = {}
            preambles = []
            for result in results:
                for k, v in six.iteritems(result.inits):
                    assert k not in inits
                    inits[k] = v
                for p in result.preambles:
                    assert p not in preambles
                    preambles.append(p)

            assert 'shared' in inits
            # ensure that the init is defined in the lowest kernel
            k0 = next(x for x in results if x.name == knl0.name)
            assert 'shared' in k0.inits
            assert 'nonshared' in inits
            assert 'nonshared_top' in inits
            assert pre[0].code in preambles
            assert pre[0].code in k0.preambles
예제 #9
0
    def _kernel_gen(self, opts, include_jac_lookup=False):
        """
        Returns a good substitute (much faster) kernel generator for various tests
        """

        # we need:
        # - a constant (to test host constant migration)
        # - a local array (to test locals), if opts.depth
        # - a few global arrays

        # create namestore
        jac_inds = determine_jac_inds(self.store.reacs, self.store.specs,
                                      RateSpecialization.fixed)
        namestore = arc.NameStore(opts, jac_inds)
        # two kernels (one for each generator)
        instructions0 = ("""
                {arg0} = {arg} + {punpack1} + {const} {{id=insn0}}
            """)
        instructions1 = ("""
                {arg1} = {arg0} + {punpack2} {{id=insn1}}
            """)

        # create mapstore
        domain = arc.creator('domain',
                             arc.kint_type, (10, ),
                             'C',
                             initializer=np.arange(10, dtype=arc.kint_type))
        mapstore = arc.MapStore(opts, domain, None)
        # create global arg
        arg = arc.creator('arg', np.float64, (arc.problem_size.name, 10),
                          opts.order)
        arg0 = arc.creator('arg0', np.float64, (arc.problem_size.name, 10),
                           opts.order)
        arg1 = arc.creator('arg1', np.float64, (arc.problem_size.name, 10),
                           opts.order)
        punpack1 = arc.creator('punpack1', np.float64,
                               (arc.problem_size.name, 10), opts.order)
        punpack2 = arc.creator('punpack2', np.float64,
                               (arc.problem_size.name, 10), opts.order)
        const = arc.creator('const',
                            np.int32, (10, ),
                            opts.order,
                            initializer=np.arange(10, dtype=np.int32),
                            is_temporary=True)
        # set args in case we need to actually generate the file
        setattr(namestore, 'arg', arg)
        setattr(namestore, 'arg0', arg0)
        setattr(namestore, 'arg1', arg1)
        setattr(namestore, 'const', const)
        setattr(namestore, 'punpack1', punpack1)
        setattr(namestore, 'punpack2', punpack2)

        # create array / array string
        arg_lp, arg_str = mapstore.apply_maps(arg, 'j', 'i')
        arg0_lp, arg0_str = mapstore.apply_maps(arg0, 'j', 'i')
        arg1_lp, arg1_str = mapstore.apply_maps(arg1, 'j', 'i')
        const_lp, const_str = mapstore.apply_maps(const, 'i')
        pun1_lp, pun1_str = mapstore.apply_maps(punpack1, 'j', 'i')
        pun2_lp, pun2_str = mapstore.apply_maps(punpack2, 'j', 'i')

        # create kernel infos
        knl0 = knl_info(
            'knl0',
            instructions0.format(arg=arg_str,
                                 arg0=arg0_str,
                                 const=const_str,
                                 punpack1=pun1_str),
            mapstore,
            kernel_data=[arg_lp, arg0_lp, const_lp, arc.work_size, pun1_lp],
            silenced_warnings=['write_race(insn0)'])

        # create generators
        gen0 = make_kernel_generator(opts,
                                     KernelType.dummy, [knl0],
                                     namestore,
                                     name=knl0.name,
                                     input_arrays=['arg'],
                                     output_arrays=['arg0'])

        # include
        knl1_data = [arg1_lp, arg0_lp, arc.work_size, pun2_lp]
        if include_jac_lookup and opts.jac_format == JacobianFormat.sparse:
            assert gen0.jacobian_lookup is not None
            look = getattr(namestore, gen0.jacobian_lookup)
            ptr = gen0.jacobian_lookup.replace('row', 'col') if 'row' in \
                gen0.jacobian_lookup else gen0.jacobian_lookup.replace('col', 'row')
            ptr = getattr(namestore, ptr)
            lookup_lp, lookup_str = mapstore.apply_maps(look, '0')
            ptr_lp, ptr_str = mapstore.apply_maps(ptr, '0')
            instructions1 += ("""
                    <>temp = {lookup} + {ptr}
                """).format(lookup=lookup_str, ptr=ptr_str)
            knl1_data += [lookup_lp, ptr_lp]

        if opts.depth:
            local = arc.creator('local',
                                np.int32, (opts.vector_width),
                                opts.order,
                                scope=scopes.LOCAL)
            local_lp, local_str = mapstore.apply_maps(local, '0')
            instructions1 += ("""
            {local} = 1
                """.format(local=local_str))
            knl1_data += [local_lp]

        knl1 = knl_info(
            'knl1',
            instructions1.format(arg0=arg0_str,
                                 arg1=arg1_str,
                                 punpack2=pun2_str),
            mapstore,
            kernel_data=knl1_data,
            silenced_warnings=['write_race(insn1)', 'write_race(insn)'])
        gen1 = make_kernel_generator(opts,
                                     KernelType.dummy, [knl0, knl1],
                                     namestore,
                                     depends_on=[gen0],
                                     name=knl1.name,
                                     input_arrays=['arg0'],
                                     output_arrays=['arg1'])
        return gen1