How to use the psyclone.f2pygen.AssignGen function in PSyclone

To help you get started, we’ve selected a few PSyclone examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github stfc / PSyclone / src / psyclone / psyGen.py View on Github external
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)
github stfc / PSyclone / src / psyclone / gocean1p0.py View on Github external
: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)
github stfc / PSyclone / src / psyclone / gocean1p0.py View on Github external
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])
github stfc / PSyclone / src / psyclone / dynamo0p1.py View on Github external
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])
github stfc / PSyclone / src / psyclone / psyGen.py View on Github external
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
github stfc / PSyclone / src / psyclone / gocean1p0.py View on Github external
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))"))
github stfc / PSyclone / src / psyclone / domain / gocean / nodes / gocean_extract_node.py View on Github external
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")
github stfc / PSyclone / src / psyclone / psyGen.py View on Github external
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)
github stfc / PSyclone / src / psyclone / psyGen.py View on Github external
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)
github stfc / PSyclone / src / psyclone / gocean1p0.py View on Github external
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]))