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
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)
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))
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)])
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]
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
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
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
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