Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
content = []
if idx == 0:
# use the first model to provide nlayers
# *** assumption that all fields operate over the same number
# of layers
assign_1 = AssignGen(type_select, lhs="topology",
rhs=arg.name+"_space%topology",
pointer=True)
assign_2 = AssignGen(type_select, lhs="nlayers",
rhs="topology%layer_count()")
content.append(assign_1)
content.append(assign_2)
iterates_over = call.iterates_over
stencil = arg.stencil
assign_3 = AssignGen(type_select, lhs=dof+"dofmap",
rhs=arg.name +
"_space%dof_map(" + iterates_over + ", " +
stencil + ")",
pointer=True)
content.append(assign_3)
type_select.addcase(["FunctionSpace_type"], content=content)
# declare our dofmap
my_decl = DeclGen(invoke_sub, datatype="integer",
entity_decls=[dof+"dofmap(:,:)"], pointer=True)
invoke_sub.add(my_decl)
# create the subroutine kernel call content
self.schedule.gen_code(invoke_sub)
parent.add(invoke_sub)
:type parent: :py:class:`psyclone.f2pygen.SubroutineGen`
'''
from psyclone.f2pygen import CallGen, DeclGen, AssignGen, CommentGen
# Create the array used to specify the iteration space of the kernel
symtab = self.root.symbol_table
garg = self._arguments.find_grid_access()
glob_size = symtab.new_symbol_name("globalsize")
symtab.add(DataSymbol(glob_size, ArrayType(INTEGER_TYPE, [2])))
parent.add(DeclGen(parent, datatype="integer", target=True,
kind="c_size_t", entity_decls=[glob_size + "(2)"]))
api_config = Config.get().api_conf("gocean1.0")
num_x = api_config.grid_properties["go_grid_nx"].fortran\
.format(garg.name)
num_y = api_config.grid_properties["go_grid_ny"].fortran\
.format(garg.name)
parent.add(AssignGen(parent, lhs=glob_size,
rhs="(/{0}, {1}/)".format(num_x, num_y)))
# Create array for the local work size argument of the kernel
local_size = symtab.new_symbol_name("localsize")
symtab.add(DataSymbol(local_size, ArrayType(INTEGER_TYPE, [2])))
parent.add(DeclGen(parent, datatype="integer", target=True,
kind="c_size_t", entity_decls=[local_size + "(2)"]))
loc_size_value = self._opencl_options['local_size']
parent.add(AssignGen(parent, lhs=local_size,
rhs="(/{0}, 1/)".format(loc_size_value)))
# Retrieve kernel name
kernel = symtab.lookup_with_tag("kernel_" + self.name).name
# Generate code to ensure data is on device
self.gen_data_on_ocl_device(parent)
entity_decls=int_decls)
invoke_sub.add(my_decl_iscalars)
if self._schedule.const_loop_bounds and self.unique_args_arrays:
# Look-up the loop bounds using the first field object in the
# list
api_config = Config.get().api_conf("gocean1.0")
xstop = api_config.grid_properties["go_grid_xstop"].fortran \
.format(self.unique_args_arrays[0])
ystop = api_config.grid_properties["go_grid_ystop"].fortran \
.format(self.unique_args_arrays[0])
position = invoke_sub.last_declaration()
invoke_sub.add(CommentGen(invoke_sub, ""),
position=["after", position])
invoke_sub.add(AssignGen(invoke_sub, lhs=self.schedule.jloop_stop,
rhs=ystop),
position=["after", position])
invoke_sub.add(AssignGen(invoke_sub, lhs=self.schedule.iloop_stop,
rhs=xstop),
position=["after", position])
invoke_sub.add(CommentGen(invoke_sub, " Look-up loop bounds"),
position=["after", position])
invoke_sub.add(CommentGen(invoke_sub, ""),
position=["after", position])
if found_gauss_quad:
gq_name = "gaussian_quadrature"
arglist.append(gauss_quad_arg.name+"%"+gq_name)
# generate the kernel call and associated use statement
parent.add(CallGen(parent, self._name, arglist))
if not self.module_inline:
parent.add(UseGen(parent, name=self._module_name,
only=True, funcnames=[self._name]))
# declare and initialise the number of layers and the number
# of degrees of freedom. Needs to be generalised.
parent.add(DeclGen(parent, datatype="integer",
entity_decls=["nlayers", "ndf"]))
new_parent, position = parent.start_parent_loop()
new_parent.add(AssignGen(new_parent, lhs="nlayers",
rhs=field_name+"%get_nlayers()"),
position=["before", position])
new_parent.add(AssignGen(new_parent, lhs="ndf",
rhs=field_name+"%vspace%get_ndf()"),
position=["before", position])
expr=arg.name + "_space=>" + arg.name +
"%function_space", typeselect=True)
invoke_sub.add(type_select)
my_typedecl = TypeDeclGen(invoke_sub,
datatype="FunctionSpace_type",
entity_decls=[arg.name+"_space"],
pointer=True)
invoke_sub.add(my_typedecl)
content = []
if idx == 0:
# use the first model to provide nlayers
# *** assumption that all fields operate over the same number
# of layers
assign_1 = AssignGen(type_select, lhs="topology",
rhs=arg.name+"_space%topology",
pointer=True)
assign_2 = AssignGen(type_select, lhs="nlayers",
rhs="topology%layer_count()")
content.append(assign_1)
content.append(assign_2)
iterates_over = call.iterates_over
stencil = arg.stencil
assign_3 = AssignGen(type_select, lhs=dof+"dofmap",
rhs=arg.name +
"_space%dof_map(" + iterates_over + ", " +
stencil + ")",
pointer=True)
content.append(assign_3)
type_select.addcase(["FunctionSpace_type"], content=content)
# declare our dofmap
ifthen.add(CommentGen(ifthen, " Create buffer on device"))
# Get the name of the list of command queues (set in
# psyGen.InvokeSchedule)
qlist = symtab.lookup_with_tag("opencl_cmd_queues").name
flag = symtab.lookup_with_tag("opencl_error").name
ifthen.add(AssignGen(ifthen, lhs=device_buff,
rhs="create_rw_buffer(" + nbytes + ")"))
ifthen.add(
AssignGen(ifthen, lhs=flag,
rhs="clEnqueueWriteBuffer({0}(1), {1}, CL_TRUE, "
"0_8, {2}, C_LOC({3}), 0, C_NULL_PTR, "
"C_LOC({4}))".format(qlist, device_buff,
nbytes, host_buff, wevent)))
if arg.type == "field":
ifthen.add(AssignGen(
ifthen, lhs="{0}%data_on_device".format(arg.name),
rhs=".true."))
# Ensure data copies have finished
ifthen.add(CommentGen(
ifthen, " Block until data copies have finished"))
ifthen.add(AssignGen(ifthen, lhs=flag,
rhs="clFinish(" + qlist + "(1))"))
post_suffix))
prog.add(call)
decl = DeclGen(prog, "real", [local_name], kind="8",
dimension=":,:", allocatable=True)
prog.add(decl)
alloc = AllocateGen(prog, [var_name],
mold="{0}".format(local_name +
post_suffix))
prog.add(alloc)
# Initialise the variable with 0, since it might contain
# values that are not set at all (halo regions, or a
# kernel might not set all values). This way the array
# comparison with the post value works as expected
# TODO #644 - create the right "0.0" type here (e.g.
# 0.0d0, ...)
assign = AssignGen(prog, local_name, "0.0d0")
prog.add(assign)
# Now add the region that was extracted here:
prog.add(CommentGen(prog, ""))
prog.add(CommentGen(prog, " RegionStart"))
# For the driver we have to re-create the code of the
# instrumented region, but in this stand-alone driver the
# arguments are not dl_esm_inf fields anymore, but simple arrays.
# Similarly, for properties we cannot use e.g. 'fld%grid%dx'
# anymore, we have to use e.g. a local variable 'dx' that has
# been created. Since we are using the existing way of creating
# the code for the instrumented region, we need to modify how
# these variables are created. We do this by temporarily
# modifying the properties in the config file.
api_config = Config.get().api_conf("gocean1.0")
local_var_name = self.local_reduction_name
var_type = self._reduction_arg.type
if var_type == "gh_real":
zero = "0.0_r_def"
kind_type = "r_def"
data_type = "real"
elif var_type == "gh_integer":
zero = "0"
kind_type = None
data_type = "integer"
else:
raise GenerationError(
"zero_reduction variable should be one of ['gh_real', "
"'gh_integer'] but found '{0}'".format(var_type))
parent.add(AssignGen(parent, lhs=var_name, rhs=zero),
position=position)
if self.reprod_reduction:
parent.add(DeclGen(parent, datatype=data_type,
entity_decls=[local_var_name],
allocatable=True, kind=kind_type,
dimension=":,:"))
nthreads = self._name_space_manager.create_name(
root_name="nthreads", context="PSyVars", label="nthreads")
if _CONFIG.reprod_pad_size < 1:
raise GenerationError(
"REPROD_PAD_SIZE in {0} should be a positive "
"integer, but it is set to '{1}'.".format(
_CONFIG.filename, _CONFIG.reprod_pad_size))
pad_size = str(_CONFIG.reprod_pad_size)
parent.add(AllocateGen(parent, local_var_name + "(" + pad_size +
"," + nthreads + ")"), position=position)
my_typedecl = TypeDeclGen(invoke_sub,
datatype="FunctionSpace_type",
entity_decls=[arg.name+"_space"],
pointer=True)
invoke_sub.add(my_typedecl)
content = []
if idx == 0:
# use the first model to provide nlayers
# *** assumption that all fields operate over the same number
# of layers
assign_1 = AssignGen(type_select, lhs="topology",
rhs=arg.name+"_space%topology",
pointer=True)
assign_2 = AssignGen(type_select, lhs="nlayers",
rhs="topology%layer_count()")
content.append(assign_1)
content.append(assign_2)
iterates_over = call.iterates_over
stencil = arg.stencil
assign_3 = AssignGen(type_select, lhs=dof+"dofmap",
rhs=arg.name +
"_space%dof_map(" + iterates_over + ", " +
stencil + ")",
pointer=True)
content.append(assign_3)
type_select.addcase(["FunctionSpace_type"], content=content)
# declare our dofmap
my_decl = DeclGen(invoke_sub, datatype="integer",
entity_decls=[dof+"dofmap(:,:)"], pointer=True)
invoke_sub.add(my_decl)
target=True, entity_decls=[arg.name]))
else:
sub.add(DeclGen(sub, datatype="INTEGER", intent="in",
target=True, entity_decls=[arg.name]))
# Declare local variables
err_name = argsetter_st.new_symbol_name("ierr")
argsetter_st.add(DataSymbol(err_name, INTEGER_TYPE))
sub.add(DeclGen(sub, datatype="integer", entity_decls=[err_name]))
# Set kernel arguments
sub.add(CommentGen(
sub,
" Set the arguments for the {0} OpenCL Kernel".format(self.name)))
for index, arg in enumerate(self.arguments.args):
sub.add(AssignGen(
sub, lhs=err_name,
rhs="clSetKernelArg({0}, {1}, C_SIZEOF({2}), C_LOC({2}))".
format(kobj, index, arg.name)))
sub.add(CallGen(
sub, "check_status",
["'clSetKernelArg: arg {0} of {1}'".format(index, self.name),
err_name]))