How to use the psyclone.f2pygen.DeclGen 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
parent.add(if_first)
            if_first.add(AssignGen(if_first, lhs="first_time", rhs=".false."))
            if_first.add(CommentGen(if_first,
                                    " Ensure OpenCL run-time is initialised "
                                    "for this PSy-layer module"))
            if_first.add(CallGen(if_first, "psy_init"))
            if_first.add(AssignGen(if_first, lhs="num_cmd_queues",
                                   rhs="get_num_cmd_queues()"))
            if_first.add(AssignGen(if_first, lhs="cmd_queues", pointer=True,
                                   rhs="get_cmd_queues()"))
            # Kernel pointers
            kernels = self.walk(self._children, Call)
            for kern in kernels:
                kernel = "kernel_" + kern.name  # TODO use namespace manager
                parent.add(
                    DeclGen(parent, datatype="integer", kind="c_intptr_t",
                            save=True, target=True, entity_decls=[kernel]))
                if_first.add(
                    AssignGen(
                        if_first, lhs=kernel,
                        rhs='get_kernel_by_name("{0}")'.format(kern.name)))

        for entity in self._children:
            entity.gen_code(parent)

        if self.opencl:
            # Ensure we block at the end of the invoke to ensure all
            # kernels have completed before we return.
            # TODO can we lift this restriction?
            # BUG this assumes only the first command queue is used
            parent.add(CommentGen(parent,
                                  " Block until all kernels have finished"))
github stfc / PSyclone / src / psyclone / gocean1p0.py View on Github external
entity_decls=[arg.name for arg in args]))

        # Scalar real grid properties
        args = [x for x in grid_prop_args
                if x.is_scalar() and x.intrinsic_type == "real"]
        if args:
            sub.add(DeclGen(sub, datatype="real", intent="in", kind="go_wp",
                            target=True,
                            entity_decls=[arg.name for arg in args]))

        # Scalar arguments
        args = args_filter(self._arguments.args, arg_types=["scalar"],
                           is_literal=False)
        for arg in args:
            if arg.space.lower() == "go_r_scalar":
                sub.add(DeclGen(
                    sub, datatype="REAL", intent="in", kind="go_wp",
                    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):
github stfc / PSyclone / src / psyclone / gocean1p0.py View on Github external
# add the subroutine argument declarations for real scalars which
        # are not global symbols
        real_decls = list(filter(lambda x: x not in global_names,
                                 self.unique_args_rscalars))
        if real_decls:
            my_decl_rscalars = DeclGen(invoke_sub, datatype="REAL",
                                       intent="inout", kind="go_wp",
                                       entity_decls=real_decls)
            invoke_sub.add(my_decl_rscalars)

        # add the subroutine argument declarations for integer scalars
        # which are not global symbols
        int_decls = list(filter(lambda x: x not in global_names,
                                self.unique_args_iscalars))
        if int_decls:
            my_decl_iscalars = DeclGen(invoke_sub, datatype="INTEGER",
                                       intent="inout",
                                       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])
github stfc / PSyclone / src / psyclone / domain / gocean / nodes / gocean_extract_node.py View on Github external
call = CallGen(prog,
                               "{0}%ReadVariable(\"{1}\", {2})"
                               .format(psy_data, var_name, local_name))
                prog.add(call)
            elif is_input:
                # Now must be input and output:
                # First read the pre-variable (which also allocates it):
                call = CallGen(prog,
                               "{0}%ReadVariable(\"{1}\", {2})"
                               .format(psy_data, var_name, local_name))
                prog.add(call)
                # Then declare the post variable, and and read its values
                # (ReadVariable will also allocate it)
                sym = Symbol(local_name+post_suffix)
                sym_table.add(sym)
                decl = DeclGen(prog, "real", [local_name+post_suffix],
                               dimension=":,:", kind="8", allocatable=True)
                prog.add(decl)
                call = CallGen(prog,
                               "{0}%ReadVariable(\"{1}{3}\", {2}{3})"
                               .format(psy_data, var_name, local_name,
                                       post_suffix))
                prog.add(call)
            else:
                # Now the variable is output only. We need to read the
                # post variable in, and create and allocate a pre variable
                # with the same size as the post
                sym = Symbol(local_name+post_suffix)
                sym_table.add(sym)
                decl = DeclGen(prog, "real", [local_name+post_suffix],
                               dimension=":,:", kind="8", allocatable=True)
                prog.add(decl)
github stfc / PSyclone / src / psyclone / gocean0p1.py View on Github external
def gen_code(self, parent):
        ''' Generates GOcean specific invocation code (the subroutine called
            by the associated invoke call in the algorithm layer). This
            consists of the PSy invocation subroutine and the declaration of
            its arguments.'''
        from psyclone.f2pygen import SubroutineGen, DeclGen, TypeDeclGen
        # create the subroutine
        invoke_sub = SubroutineGen(parent, name=self.name,
                                   args=self.psy_unique_var_names)
        parent.add(invoke_sub)
        self.schedule.gen_code(invoke_sub)
        # add the subroutine argument declarations for arrays
        if len(self.unique_args_arrays) > 0:
            my_decl_arrays = DeclGen(invoke_sub, datatype="REAL",
                                     intent="inout", kind="go_wp",
                                     entity_decls=self.unique_args_arrays,
                                     dimension=":,:")
            invoke_sub.add(my_decl_arrays)
        # add the subroutine argument declarations for scalars
        if len(self.unique_args_scalars) > 0:
            my_decl_scalars = \
                TypeDeclGen(invoke_sub,
                            datatype="scalar_field_type",
                            entity_decls=self.unique_args_scalars,
                            intent="inout")
            invoke_sub.add(my_decl_scalars)
github stfc / PSyclone / src / psyclone / gocean1p0.py View on Github external
.fortran.format(arg.name)
                else:
                    # grid properties do not have such an attribute (because
                    # they are just pointers) so we check whether the device
                    # pointer is NULL.
                    device_buff = "{0}%grid%{1}_device".format(grid_arg.name,
                                                               arg.name)
                    condition = device_buff + " == 0"
                    host_buff = "{0}%grid%{1}".format(grid_arg.name, arg.name)
                # Name of variable to hold no. of bytes of storage required
                nbytes = symtab.lookup_with_tag("opencl_bytes").name
                # Variable to hold write event returned by OpenCL runtime
                wevent = symtab.lookup_with_tag("opencl_wevent").name
                ifthen = IfThenGen(parent, condition)
                parent.add(ifthen)
                parent.add(DeclGen(parent, datatype="integer", kind="c_size_t",
                                   entity_decls=[nbytes]))
                parent.add(DeclGen(parent, datatype="integer",
                                   kind="c_intptr_t", target=True,
                                   entity_decls=[wevent]))
                api_config = Config.get().api_conf("gocean1.0")
                props = api_config.grid_properties
                num_x = props["go_grid_nx"].fortran.format(grid_arg.name)
                num_y = props["go_grid_ny"].fortran.format(grid_arg.name)
                # Use c_sizeof() on first element of array to be copied over in
                # order to cope with the fact that some grid properties are
                # integer.
                size_expr = "int({0}*{1}, 8)*c_sizeof({2}(1,1))" \
                            .format(num_x, num_y, host_buff)
                ifthen.add(AssignGen(ifthen, lhs=nbytes, rhs=size_expr))
                ifthen.add(CommentGen(ifthen, " Create buffer on device"))
                # Get the name of the list of command queues (set in
github stfc / PSyclone / src / psyclone / dynamo0p1.py View on Github external
def gen_code(self, parent):
        ''' Generates dynamo version 0.1 specific psy code for a call to
            the dynamo kernel instance. '''
        from psyclone.f2pygen import CallGen, DeclGen, AssignGen, UseGen

        # TODO: we simply choose the first field as the lookup for the moment
        field_name = self.arguments.args[0].name

        # add a dofmap lookup using first field.
        # TODO: This needs to be generalised to work for multiple dofmaps
        parent.add(CallGen(parent, field_name+"%vspace%get_cell_dofmap",
                           ["cell", "map"]))
        parent.add(DeclGen(parent, datatype="integer",
                           entity_decls=["cell"]))
        parent.add(DeclGen(parent, datatype="integer", pointer=True,
                           entity_decls=["map(:)"]))

        # create the argument list on the fly so we can also create
        # appropriate variables and lookups
        arglist = []
        arglist.append("nlayers")
        arglist.append("ndf")
        arglist.append("map")

        found_gauss_quad = False
        gauss_quad_arg = None
        for arg in self._arguments.args:
            if arg.requires_basis:
                basis_name = arg.function_space+"_basis_"+arg.name
github stfc / PSyclone / src / psyclone / psyGen.py View on Github external
# create the subroutine
        invoke_sub = SubroutineGen(parent, name=self.name,
                                   args=self.psy_unique_vars)
        # add the subroutine argument declarations
        my_typedecl = TypeDeclGen(invoke_sub, datatype="field_type",
                                  entity_decls=self.psy_unique_vars,
                                  intent="inout")
        invoke_sub.add(my_typedecl)
        # declare field-type, column topology and function-space types
        column_topology_name = "topology"
        my_typedecl = TypeDeclGen(invoke_sub, datatype="ColumnTopology",
                                  entity_decls=[column_topology_name],
                                  pointer=True)
        invoke_sub.add(my_typedecl)
        # declare any basic types required
        my_decl = DeclGen(invoke_sub, datatype="integer",
                          entity_decls=["nlayers"])
        invoke_sub.add(my_decl)

        for (idx, dof) in enumerate(self._dofs):
            call = self._dofs[dof][0]
            arg = self._dofs[dof][1]
            # declare a type select clause which is used to map from a base
            # class to FunctionSpace_type
            type_select = SelectionGen(invoke_sub,
                                       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"],
github stfc / PSyclone / src / psyclone / gocean0p1.py View on Github external
def gen_code(self, parent):

        if self.field_space == "every":
            from psyclone.f2pygen import DeclGen
            from psyclone.psyir.nodes import BinaryOperation
            dim_var = DeclGen(parent, datatype="INTEGER",
                              entity_decls=[self.variable.name])
            parent.add(dim_var)

            # Update start loop bound
            self.start_expr = Literal("1", INTEGER_TYPE, parent=self)

            # Update stop loop bound
            if self._loop_type == "inner":
                index = "1"
            elif self._loop_type == "outer":
                index = "2"
            self.stop_expr = BinaryOperation(BinaryOperation.Operator.SIZE,
                                             parent=self)
            self.stop_expr.addchild(
                Reference(DataSymbol(self.field_name, INTEGER_TYPE),
                          parent=self.stop_expr))