def gen_code(self, parent):
     from f2pygen import AssignGen
     # We copy one element of field A (first arg) to the
     # corresponding element of field B (second arg).
     invar_name = self.array_ref(self._arguments.args[0].proxy_name)
     outvar_name = self.array_ref(self._arguments.args[1].proxy_name)
     parent.add(AssignGen(parent, lhs=outvar_name, rhs=invar_name))
 def gen_code(self, parent):
     from f2pygen import AssignGen
     # In this case we're assigning a single scalar value to all
     # elements of a field.
     var_name = self.array_ref(self._arguments.args[1].proxy_name)
     value = self._arguments.args[0]
     parent.add(AssignGen(parent, lhs=var_name, rhs=value))
 def gen_code(self, parent):
     from f2pygen import AssignGen
     # We sum the DoF-wise product of the supplied fields. The variable
     # holding the sum is initialised to zero in the psy layer.
     sum_name = self._reduction_ref(self._arguments.args[1].name)
     invar_name1 = self.array_ref(self._arguments.args[0].proxy_name)
     rhs_expr = sum_name + "+" + invar_name1 + "*" + invar_name1
     parent.add(AssignGen(parent, lhs=sum_name, rhs=rhs_expr))
 def gen_code(self, parent):
     from f2pygen import AssignGen
     # We add each element of f1 to the corresponding element of f2
     # and store the result back in f1.
     invar_name1 = self.array_ref(self._arguments.args[0].proxy_name)
     invar_name2 = self.array_ref(self._arguments.args[1].proxy_name)
     parent.add(AssignGen(parent, lhs=invar_name1,
                          rhs=invar_name1 + " + " + invar_name2))
 def gen_code(self, parent):
     from f2pygen import AssignGen
     # In this case we're raising each element of a field to a
     # supplied scalar value.
     var_name = self.array_ref(self._arguments.args[0].proxy_name)
     value = self._arguments.args[1].name
     parent.add(AssignGen(parent, lhs=var_name,
                          rhs=var_name + "**" + value))
 def gen_code(self, parent):
     from f2pygen import AssignGen
     # Sum all the elements of a field. The variable holding the
     # sum is initialised to zero in the psy layer.
     fld_name = self.array_ref(self._arguments.args[0].proxy_name)
     sum_name = self._reduction_ref(self._arguments.args[1].name)
     rhs_expr = sum_name + "+" + fld_name
     parent.add(AssignGen(parent, lhs=sum_name, rhs=rhs_expr))
 def gen_code(self, parent):
     from f2pygen import AssignGen
     # We multiply each element of f1 by the scalar argument and
     # store the result in f2.
     scalar_name = self._arguments.args[0].name
     invar_name = self.array_ref(self._arguments.args[1].proxy_name)
     outvar_name = self.array_ref(self._arguments.args[2].proxy_name)
     parent.add(AssignGen(parent, lhs=outvar_name,
                          rhs=scalar_name + " * " + invar_name))
 def gen_code(self, parent):
     from f2pygen import AssignGen
     # We divide each element of f1 by the corresponding element of
     # f2 and store the result in f3.
     invar_name1 = self.array_ref(self._arguments.args[0].proxy_name)
     invar_name2 = self.array_ref(self._arguments.args[1].proxy_name)
     outvar_name = self.array_ref(self._arguments.args[2].proxy_name)
     parent.add(AssignGen(parent, lhs=outvar_name,
                          rhs=invar_name1 + " / " + invar_name2))
 def gen_code(self, parent):
     from f2pygen import AssignGen
     # We multiply one element of field f2 (3rd arg) by a scalar (2nd arg),
     # add it to the corresponding element of a first field f1 (1st arg)
     # and write the value back into the element of field f1.
     scalar_name = self._arguments.args[1].name
     invar_name1 = self.array_ref(self._arguments.args[0].proxy_name)
     invar_name2 = self.array_ref(self._arguments.args[2].proxy_name)
     rhs_expr = invar_name1 + " + " + scalar_name + "*" + invar_name2
     parent.add(AssignGen(parent, lhs=invar_name1, rhs=rhs_expr))
 def gen_code(self, parent):
     from f2pygen import AssignGen
     # We subtract each element of f2 from the corresponding element
     # of f1 and store the result in f3.
     invar_name1 = self.array_ref(self._arguments.args[0].proxy_name)
     invar_name2 = self.array_ref(self._arguments.args[1].proxy_name)
     outvar_name = self.array_ref(self._arguments.args[2].proxy_name)
     assign = AssignGen(parent, lhs=outvar_name,
                        rhs=invar_name1 + " - " + invar_name2)
     parent.add(assign)
 def gen_code(self, parent):
     from f2pygen import AssignGen
     # We multiply one element of field f1 (2nd arg) by a scalar
     # (1st arg), add it to the corresponding element of a
     # second field (3rd arg) and write the value back into
     # the element of field f1.
     scalar_name = self._arguments.args[0].name
     fld_name1 = self.array_ref(self._arguments.args[1].proxy_name)
     fld_name2 = self.array_ref(self._arguments.args[2].proxy_name)
     rhs_expr = scalar_name + "*" + fld_name1 + " + " + fld_name2
     parent.add(AssignGen(parent, lhs=fld_name1, rhs=rhs_expr))
 def gen_code(self, parent):
     from f2pygen import AssignGen
     # We multiply one element of field f1 (2nd arg) by a scalar
     # (1st arg), add it to the corresponding
     # element of a second field (3rd arg)  and write the value to the
     # corresponding element of field f3 (4th arg).
     scalar_name = self._arguments.args[0].name
     invar_name1 = self.array_ref(self._arguments.args[1].proxy_name)
     invar_name2 = self.array_ref(self._arguments.args[2].proxy_name)
     outvar_name = self.array_ref(self._arguments.args[3].proxy_name)
     rhs_expr = scalar_name + "*" + invar_name1 + " + " + invar_name2
     parent.add(AssignGen(parent, lhs=outvar_name, rhs=rhs_expr))
 def gen_code(self, parent):
     from f2pygen import AssignGen
     # We multiply one element of field f1 (2nd arg) by the first scalar
     # (1st arg), add it to the product of the corresponding element of
     # a second field (4th arg) with the second scalar (4rd arg) and
     # write the value back into the element of field f1.
     scalar_name1 = self._arguments.args[0].name
     scalar_name2 = self._arguments.args[2].name
     invar_name1 = self.array_ref(self._arguments.args[1].proxy_name)
     invar_name2 = self.array_ref(self._arguments.args[3].proxy_name)
     rhs_expr = (scalar_name1 + "*" + invar_name1 + " + " +
                 scalar_name2 + "*" + invar_name2)
     parent.add(AssignGen(parent, lhs=invar_name1, rhs=rhs_expr))
Exemple #14
0
    def gen_code(self, parent):
        ''' Generates dynamo version 0.1 specific psy code for a call to
            the dynamo kernel instance. '''
        from 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
                arglist.append(basis_name)
                new_parent, position = parent.start_parent_loop()
                new_parent.add(CallGen(new_parent,
                                       field_name + "%vspace%get_basis",
                                       [basis_name]),
                               position=["before", position])
                parent.add(
                    DeclGen(parent,
                            datatype="real",
                            kind="dp",
                            pointer=True,
                            entity_decls=[basis_name + "(:,:,:,:,:)"]))
            if arg.requires_diff_basis:
                raise GenerationError("differential basis has not yet "
                                      "been coded")
            if arg.requires_gauss_quad:
                if found_gauss_quad:
                    raise GenerationError("found more than one gaussian "
                                          "quadrature in this kernel")
                found_gauss_quad = True
                gauss_quad_arg = arg
            dataref = "%data"
            arglist.append(arg.name + dataref)

        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])
Exemple #15
0
    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 f2pygen import SubroutineGen, DeclGen, TypeDeclGen, CommentGen,\
            AssignGen
        # create the subroutine
        invoke_sub = SubroutineGen(parent,
                                   name=self.name,
                                   args=self.psy_unique_var_names)
        parent.add(invoke_sub)

        # add declarations for the variables holding the upper bounds
        # of loops in i and j
        if self.schedule.const_loop_bounds:
            invoke_sub.add(
                DeclGen(invoke_sub,
                        datatype="INTEGER",
                        entity_decls=[
                            self.schedule.iloop_stop, self.schedule.jloop_stop
                        ]))

        # Generate the code body of this subroutine
        self.schedule.gen_code(invoke_sub)

        # add the subroutine argument declarations for fields
        if len(self.unique_args_arrays) > 0:
            my_decl_arrays = TypeDeclGen(invoke_sub,
                                         datatype="r2d_field",
                                         intent="inout",
                                         entity_decls=self.unique_args_arrays)
            invoke_sub.add(my_decl_arrays)

        # add the subroutine argument declarations for real scalars
        if len(self.unique_args_rscalars) > 0:
            my_decl_rscalars = DeclGen(invoke_sub,
                                       datatype="REAL",
                                       intent="inout",
                                       kind="wp",
                                       entity_decls=self.unique_args_rscalars)
            invoke_sub.add(my_decl_rscalars)
        # add the subroutine argument declarations for integer scalars
        if len(self.unique_args_iscalars) > 0:
            my_decl_iscalars = DeclGen(invoke_sub,
                                       datatype="INTEGER",
                                       intent="inout",
                                       entity_decls=self.unique_args_iscalars)
            invoke_sub.add(my_decl_iscalars)

        if self._schedule.const_loop_bounds and \
           len(self.unique_args_arrays) > 0:

            # Look-up the loop bounds using the first field object in the
            # list
            sim_domain = self.unique_args_arrays[0] +\
                "%grid%simulation_domain%"
            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=sim_domain + "ystop"),
                           position=["after", position])
            invoke_sub.add(AssignGen(invoke_sub,
                                     lhs=self.schedule.iloop_stop,
                                     rhs=sim_domain + "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])