Example #1
0
def test_constructor():
    '''Test the optional constructor parameter (single node and list
    of nodes).'''
    from psyclone.tests.utilities import create_schedule
    code = '''module test
        contains
        subroutine tmp()
          integer :: a,b,c
          a = b/c
          c = a*b
        end subroutine tmp
        end module test'''
    schedule = create_schedule(code, "tmp")
    node1 = schedule[0]
    node2 = schedule[1]
    vai1 = VariablesAccessInfo(node1)
    assert str(vai1) == "a: WRITE, b: READ, c: READ"
    vai2 = VariablesAccessInfo([node1, node2])
    assert str(vai2) == "a: READ+WRITE, b: READ, c: READ+WRITE"

    with pytest.raises(InternalError) as err:
        VariablesAccessInfo([node1, node2, 3])
    assert "One element in the node list is not a Node, but of type " in \
        str(err.value)
    # The error message is slightly different between python 2 and 3
    # so only test for the part that is the same in both:
    assert "'int'>" in str(err.value)

    with pytest.raises(InternalError) as err:
        VariablesAccessInfo(1)
    assert "Error in VariablesAccessInfo" in str(err.value)
    # The error message is slightly different between python 2 and 3
    # so only test for the part that is the same in both:
    assert "'int'>" in str(err.value)
Example #2
0
def test_reference_accesses_bounds(operator_type):
    '''Test that the reference_accesses method behaves as expected when
    the reference is the first argument to either the lbound or ubound
    intrinsic as that is simply looking up the array bounds (therefore
    var_access_info should be empty) and when the reference is the
    second argument of either the lbound or ubound intrinsic (in which
    case the access should be a read).

    '''
    # Note, one would usually expect UBOUND to provide the upper bound
    # of a range but to simplify the test both LBOUND and UBOUND are
    # used for the lower bound. This does not affect the test.
    one = Literal("1", INTEGER_TYPE)
    array_symbol = DataSymbol("test", ArrayType(REAL_TYPE, [10]))
    array_ref1 = Reference(array_symbol)
    array_ref2 = Reference(array_symbol)
    array_access = Array.create(array_symbol, [one])

    # test when first or second argument to LBOUND or UBOUND is an
    # array reference
    operator = BinaryOperation.create(operator_type, array_ref1, array_ref2)
    array_access.children[0] = Range.create(operator, one, one)
    var_access_info = VariablesAccessInfo()
    array_ref1.reference_accesses(var_access_info)
    assert str(var_access_info) == ""
    var_access_info = VariablesAccessInfo()
    array_ref2.reference_accesses(var_access_info)
    assert str(var_access_info) == "test: READ"
Example #3
0
def test_lfric_stub_cma_operators():
    '''Check variable usage detection cma operators.
    mesh_ncell2d, cma_operator

    '''
    from psyclone.dynamo0p3 import DynKernMetadata, DynKern
    from psyclone.domain.lfric import KernStubArgList
    ast = get_ast("dynamo0.3", "columnwise_op_mul_2scalars_kernel_mod.F90")
    metadata = DynKernMetadata(ast)
    kernel = DynKern()
    kernel.load_meta(metadata)
    var_accesses = VariablesAccessInfo()
    create_arg_list = KernStubArgList(kernel)
    create_arg_list.generate(var_accesses=var_accesses)
    var_info = str(var_accesses)
    for num in ["1", "3", "5"]:
        assert "ncell_2d: READ" in var_info
        assert "cma_op_"+num+": READ" in var_info
        assert "cma_op_"+num+"_nrow: READ" in var_info
        assert "cma_op_"+num+"_ncol: READ" in var_info
        assert "cma_op_"+num+"_bandwidth: READ" in var_info
        assert "cma_op_"+num+"_alpha: READ" in var_info
        assert "cma_op_"+num+"_beta: READ" in var_info
        assert "cma_op_"+num+"_gamma_m: READ" in var_info
        assert "cma_op_"+num+"_gamma_p: READ" in var_info
Example #4
0
def test_if_statement(parser):
    ''' Tests handling an if statement
    '''
    reader = FortranStringReader('''program test_prog
                                 integer :: a, b, i
                                 real, dimension(5) :: p, q, r
                                 if (a .eq. b) then
                                    p(i) = q(i)
                                 else
                                   q(i) = r(i)
                                 endif
                                 end program test_prog''')
    ast = parser(reader)
    psy = PSyFactory(API).create(ast)
    schedule = psy.invokes.get("test_prog").schedule

    if_stmt = schedule.children[0]
    assert isinstance(if_stmt, IfBlock)
    var_accesses = VariablesAccessInfo(if_stmt)
    assert str(var_accesses) == "a: READ, b: READ, i: READ, p: WRITE, "\
                                "q: READ+WRITE, r: READ"
    # Test that the two accesses to 'q' indeed show up as
    q_accesses = var_accesses["q"].all_accesses
    assert len(q_accesses) == 2
    assert q_accesses[0].access_type == AccessType.READ
    assert q_accesses[1].access_type == AccessType.WRITE
    assert q_accesses[0].location < q_accesses[1].location
Example #5
0
    def gen_code(self, parent):
        # pylint: disable=arguments-differ
        '''
        Generates the code required for read-only verification of one or
        more Nodes. It uses the PSyData API (via the base class PSyDataNode)
        to create the required callbacks that will allow a library to
        validate that read-only data is not modified.

        :param parent: the parent of this Node in the PSyIR.
        :type parent: :py:class:`psyclone.psyir.nodes.Node`.
        '''

        # Determine the variables to validate:
        from psyclone.core.access_info import VariablesAccessInfo
        variables_info = VariablesAccessInfo(self)
        read_only = []
        for var_name in variables_info:
            if variables_info[var_name].is_read_only():
                read_only.append(var_name)

        # Add a callback here so that derived classes can adjust the list
        # of variables to provide, or the suffix used (which might
        # depend on the variable name which could create clashes).
        self.update_vars_and_postname()

        options = {'pre_var_list': read_only, 'post_var_list': read_only}

        from psyclone.f2pygen import CommentGen
        parent.add(CommentGen(parent, ""))
        parent.add(CommentGen(parent, " ReadOnlyVerifyStart"))
        parent.add(CommentGen(parent, ""))
        super(ReadOnlyVerifyNode, self).gen_code(parent, options)
        parent.add(CommentGen(parent, ""))
        parent.add(CommentGen(parent, " ReadOnlyVerifyEnd"))
        parent.add(CommentGen(parent, ""))
Example #6
0
def test_lfric_acc():
    '''Check variable usage detection when OpenACC is used.

    '''
    # Use the OpenACC transforms to enclose the kernels
    # with OpenACC directives.
    from psyclone.transformations import ACCParallelTrans, ACCEnterDataTrans
    from psyclone.psyGen import CodedKern
    acc_par_trans = ACCParallelTrans()
    acc_enter_trans = ACCEnterDataTrans()
    _, invoke = get_invoke("1_single_invoke.f90", "dynamo0.3",
                           name="invoke_0_testkern_type", dist_mem=False)
    sched = invoke.schedule
    _ = acc_par_trans.apply(sched.children)
    _ = acc_enter_trans.apply(sched)

    # Find the first kernel:
    kern = invoke.schedule.walk(CodedKern)[0]
    create_acc_arg_list = KernCallAccArgList(kern)
    var_accesses = VariablesAccessInfo()
    create_acc_arg_list.generate(var_accesses=var_accesses)
    var_info = str(var_accesses)
    assert "f1: READ+WRITE" in var_info
    assert "f2: READ" in var_info
    assert "m1: READ" in var_info
    assert "m2: READ" in var_info
    assert "undf_w1: READ" in var_info
    assert "map_w1: READ" in var_info
    assert "undf_w2: READ" in var_info
    assert "map_w2: READ" in var_info
    assert "undf_w3: READ" in var_info
    assert "map_w3: READ" in var_info
Example #7
0
def test_lfric_acc_operator():
    '''Check variable usage detection when OpenACC is used with
    a kernel that uses an operator.

    '''
    # Use the OpenACC transforms to enclose the kernels
    # with OpenACC directives.
    from psyclone.transformations import ACCParallelTrans, ACCEnterDataTrans
    from psyclone.psyGen import CodedKern
    acc_par_trans = ACCParallelTrans()
    acc_enter_trans = ACCEnterDataTrans()
    _, invoke = get_invoke("20.0_cma_assembly.f90", "dynamo0.3",
                           idx=0, dist_mem=False)
    sched = invoke.schedule
    _ = acc_par_trans.apply(sched.children)
    _ = acc_enter_trans.apply(sched)

    # Find the first kernel:
    kern = invoke.schedule.walk(CodedKern)[0]
    create_acc_arg_list = KernCallAccArgList(kern)
    var_accesses = VariablesAccessInfo()
    create_acc_arg_list.generate(var_accesses=var_accesses)
    var_info = str(var_accesses)
    assert "lma_op1_proxy%ncell_3d: READ" in var_info
    assert "lma_op1_proxy%local_stencil: WRITE" in var_info
Example #8
0
def test_lfric_stencil():
    '''Check variable usage detection when OpenACC is used with a
    kernel that uses a stencil.

    '''
    # Use the OpenACC transforms to create the required kernels
    from psyclone.transformations import ACCParallelTrans, ACCEnterDataTrans
    from psyclone.psyGen import CodedKern
    acc_par_trans = ACCParallelTrans()
    acc_enter_trans = ACCEnterDataTrans()
    _, invoke = get_invoke("14.4_halo_vector.f90", "dynamo0.3",
                           idx=0, dist_mem=False)
    sched = invoke.schedule
    _ = acc_par_trans.apply(sched.children)
    _ = acc_enter_trans.apply(sched)

    # Find the first kernel:
    kern = invoke.schedule.walk(CodedKern)[0]
    create_acc_arg_list = KernCallAccArgList(kern)
    var_accesses = VariablesAccessInfo()
    create_acc_arg_list.generate(var_accesses=var_accesses)
    var_info = str(var_accesses)
    assert "f1: READ+WRITE" in var_info
    assert "f2: READ" in var_info
    assert "f2_stencil_dofmap: READ" in var_info
Example #9
0
    def get_input_parameters(self, node_list, variables_info=None):
        # pylint: disable=no-self-use
        '''Return all variables that are input parameters, i.e. are
        read (before potentially being written).

        :param node_list: list of PSyIR nodes to be analysed.
        :type node_list: list of :py:class:`psyclone.psyir.nodes.Node`
        :param variables_info: optional variable usage information, \
            can be used to avoid repeatedly collecting this information.
        :type variables_info: \
            :py:class:`psyclone.core.variables_info.VariablesAccessInfo`

        :returns: a list of all variable names that are read.
        :rtype: list of str

        '''
        # Collect the information about all variables used:
        if not variables_info:
            variables_info = VariablesAccessInfo(node_list)

        input_list = []
        for var_name in variables_info.all_vars:
            # Take the first access (index 0) of this variable. Note that
            # loop variables have a WRITE before a READ access, so they
            # will be ignored
            first_access = variables_info[var_name][0]
            # If the first access is a write, the variable is not an input
            # parameter and does not need to be saved.
            if first_access.access_type != AccessType.WRITE:
                input_list.append(var_name)

        return input_list
Example #10
0
def test_lfric_stub_args():
    '''Check that correct stub code is produced when there are multiple
    stencils.

    '''
    ast = get_ast("dynamo0.3", "testkern_stencil_multi_mod.f90")
    metadata = DynKernMetadata(ast)
    kernel = DynKern()
    kernel.load_meta(metadata)
    var_accesses = VariablesAccessInfo()
    create_arg_list = KernStubArgList(kernel)
    create_arg_list.generate(var_accesses=var_accesses)
    var_info = str(var_accesses)
    assert "field_1_w1: READ+WRITE" in var_info
    assert "field_2_stencil_dofmap: READ" in var_info
    assert "field_2_stencil_size: READ" in var_info
    assert "field_2_w2: READ" in var_info
    assert "field_3_direction: READ" in var_info
    assert "field_3_stencil_dofmap: READ" in var_info
    assert "field_3_stencil_size: READ" in var_info
    assert "field_3_w2: READ" in var_info
    assert "field_4_stencil_dofmap: READ" in var_info
    assert "field_4_stencil_size: READ" in var_info
    assert "field_4_w3: READ" in var_info
    assert "map_w1: READ" in var_info
    assert "map_w2: READ" in var_info
    assert "map_w3: READ" in var_info
    assert "ndf_w1: READ" in var_info
    assert "ndf_w2: READ" in var_info
    assert "ndf_w3: READ" in var_info
    assert "nlayers: READ" in var_info
    assert "undf_w1: READ" in var_info
    assert "undf_w2: READ" in var_info
    assert "undf_w3: READ" in var_info
Example #11
0
def test_goloop_field_accesses():
    ''' Check that for a GOcean kernel appropriate field accesses (based
    on the meta data) are added to the dependency analysis.

    '''
    _, invoke = get_invoke("large_stencil.f90",
                           "gocean1.0",
                           name="invoke_large_stencil",
                           dist_mem=False)
    do_loop = invoke.schedule.children[0]

    assert isinstance(do_loop, Loop)
    var_accesses = VariablesAccessInfo(invoke.schedule)

    # cu_fld has a pointwise write access in the first loop:
    cu_fld = var_accesses["cu_fld"]
    assert len(cu_fld.all_accesses) == 1
    assert cu_fld.all_accesses[0].access_type == AccessType.WRITE
    assert cu_fld.all_accesses[0].indices == ["i", "j"]

    # The stencil is defined to be GO_STENCIL(123,110,100)) for
    # p_fld. Make sure that these 9 accesses are indeed reported:
    p_fld = var_accesses["p_fld"]
    all_indices = [access.indices for access in p_fld.all_accesses]

    for test_index in [["i-1", "j+1"], ["i", "j+1"], ["i", "j+2"],
                       ["i+1", "j+1"], ["i+2", "j+2"], ["i+3", "j+3"],
                       ["i-1", "j"], ["i", "j"], ["i-1", "j-1"]]:
        assert test_index in all_indices

    # Since we have 9 different indices found (above), the following
    # test guarantees that we don't get any invalid accesses reported.
    assert len(p_fld.all_accesses) == 9
Example #12
0
def test_lfric_stencils():
    '''Test that stencil parameters are correctly detected.

    '''
    _, invoke_info = get_invoke("14.4_halo_vector.f90", "dynamo0.3", idx=0)
    var_info = str(VariablesAccessInfo(invoke_info.schedule))
    assert "f2_stencil_size: READ" in var_info
    assert "f2_stencil_dofmap: READ" in var_info
Example #13
0
def test_reference_accesses():
    '''Test that the reference_accesses method behaves as expected in the
    usual case (see the next test for the unusual case).

    '''
    reference = Reference(DataSymbol("test", REAL_TYPE))
    var_access_info = VariablesAccessInfo()
    reference.reference_accesses(var_access_info)
    assert (str(var_access_info)) == "test: READ"
Example #14
0
def test_lfric_operator():
    '''Check if implicit basis and differential basis variables are
    handled correctly.

    '''
    _, invoke_info = get_invoke("6.1_eval_invoke.f90", "dynamo0.3", idx=0)
    var_info = str(VariablesAccessInfo(invoke_info.schedule))
    assert "basis_w0_on_w0: READ" in var_info
    assert "diff_basis_w1_on_w0: READ" in var_info
Example #15
0
def test_lfric_operator_bc_kernel():
    '''Tests that a kernel that applies boundary conditions to operators
    detects the right implicit paramaters.

    '''
    _, invoke_info = get_invoke("12.4_enforce_op_bc_kernel.f90",
                                "dynamo0.3", idx=0)
    var_info = str(VariablesAccessInfo(invoke_info.schedule))
    assert "boundary_dofs_op_a: READ" in var_info
Example #16
0
def test_lfric_field_bc_kernel():
    '''Tests that implicit parameters in case of a boundary_dofs
    array fix are created correctly.

    '''
    _, invoke_info = get_invoke("12.2_enforce_bc_kernel.f90",
                                "dynamo0.3", idx=0)
    var_info = str(VariablesAccessInfo(invoke_info.schedule))
    assert "boundary_dofs_a: READ" in var_info
Example #17
0
def test_lfric_stencil_xory_vector():
    '''Test that the implicit parameters for a stencil access of type x
    or y with a vector field are created.

    '''
    _, invoke_info = get_invoke("14.4.2_halo_vector_xory.f90",
                                "dynamo0.3", idx=0)
    var_info = str(VariablesAccessInfo(invoke_info.schedule))
    assert "f2_direction: READ" in var_info
Example #18
0
def test_lfric_cma2():
    '''Test that parameters related to CMA operators are handled
    correctly in the variable usage analysis.

    '''
    _, invoke_info = get_invoke("20.1_cma_apply.f90", "dynamo0.3", idx=0)
    var_info = str(VariablesAccessInfo(invoke_info.schedule))
    assert "cma_indirection_map_aspc1_field_a: READ" in var_info
    assert "cma_indirection_map_aspc2_field_b: READ" in var_info
Example #19
0
def test_reference_accesses():
    ''' Test that the reference_accesses method does nothing. This will
    be addressed by #1028. '''
    var_access_info = VariablesAccessInfo()
    dref = nodes.StructureReference.create(
        symbols.DataSymbol(
            "grid", symbols.TypeSymbol("grid_type", symbols.DeferredType())),
        ["data"])
    dref.reference_accesses(var_access_info)
    assert var_access_info.all_signatures == []
Example #20
0
def test_lfric_ref_element():
    '''Test handling of variables if an LFRic's RefElement is used.

    '''
    _, invoke_info = get_invoke("23.4_ref_elem_all_faces_invoke.f90",
                                "dynamo0.3", idx=0)
    var_info = str(VariablesAccessInfo(invoke_info.schedule))
    assert "normals_to_faces: READ" in var_info
    assert "out_normals_to_faces: READ" in var_info
    assert "nfaces_re: READ" in var_info
Example #21
0
def test_lfric_stub_boundary_dofs():
    '''Check variable usage detection for boundary dofs.

    '''
    ast = get_ast("dynamo0.3", "enforce_bc_kernel_mod.f90")
    metadata = DynKernMetadata(ast)
    kernel = DynKern()
    kernel.load_meta(metadata)
    var_accesses = VariablesAccessInfo()
    create_arg_list = KernStubArgList(kernel)
    create_arg_list.generate(var_accesses=var_accesses)
    assert "boundary_dofs_field_1: READ" in str(var_accesses)
Example #22
0
def test_lfric_stub_indirection_dofmap():
    '''Check variable usage detection in indirection dofmap.
    '''
    ast = get_ast("dynamo0.3", "columnwise_op_app_kernel_mod.F90")
    metadata = DynKernMetadata(ast)
    kernel = DynKern()
    kernel.load_meta(metadata)
    var_accesses = VariablesAccessInfo()
    create_arg_list = KernStubArgList(kernel)
    create_arg_list.generate(var_accesses=var_accesses)
    var_info = str(var_accesses)
    assert "cma_indirection_map_aspc1_field_1: READ" in var_info
    assert "cma_indirection_map_aspc2_field_2: READ" in var_info
Example #23
0
def test_lfric_stub_banded_dofmap():
    '''Check variable usage detection for banded dofmaps.

    '''
    ast = get_ast("dynamo0.3", "columnwise_op_asm_kernel_mod.F90")
    metadata = DynKernMetadata(ast)
    kernel = DynKern()
    kernel.load_meta(metadata)
    var_accesses = VariablesAccessInfo()
    create_arg_list = KernStubArgList(kernel)
    create_arg_list.generate(var_accesses=var_accesses)
    var_info = str(var_accesses)
    assert "cbanded_map_adspc1_op_1: READ" in var_info
    assert "cbanded_map_adspc2_op_1: READ" in var_info
Example #24
0
def test_call(parser):
    ''' Check that we correctly handle a call in a program '''
    reader = FortranStringReader('''program test_prog
                                 real :: a, b
                                 call sub(a,b)
                                 end program test_prog''')
    ast = parser(reader)
    psy = PSyFactory(API).create(ast)
    schedule = psy.invokes.get("test_prog").schedule

    code_block = schedule.children[0]
    call_stmt = code_block.statements[0]
    var_accesses = VariablesAccessInfo(call_stmt)
    assert str(var_accesses) == "a: UNKNOWN, b: UNKNOWN"
Example #25
0
    def reference_accesses(self, var_accesses):
        '''Get all variable access information from this node. The assigned-to
        variable will be set to 'WRITE'.

        :param var_accesses: VariablesAccessInfo instance that stores the \
            information about variable accesses.
        :type var_accesses: \
            :py:class:`psyclone.core.access_info.VariablesAccessInfo`

        '''
        # It is important that a new instance is used to handle the LHS,
        # since a check in 'change_read_to_write' makes sure that there
        # is only one access to the variable!
        accesses_left = VariablesAccessInfo()
        self.lhs.reference_accesses(accesses_left)

        # Now change the (one) access to the assigned variable to be WRITE:
        if isinstance(self.lhs, CodeBlock):
            # TODO #363: Assignment to user defined type, not supported yet.
            # Here an absolute hack to get at least some information out
            # from the AST - though indices are just strings, which will
            # likely cause problems later as well.
            name = str(self.lhs.ast)
            # A regular expression that tries to find the last parenthesis
            # pair in the name ("a(i,j)" --> "(i,j)")
            ind = re.search(r"\([^\(]+\)$", name)
            if ind:
                # Remove the index part of the name
                name = name.replace(ind.group(0), "")
                # The index must be added as a list
                accesses_left.add_access(name, AccessType.WRITE, self,
                                         [ind.group(0)])
            else:
                accesses_left.add_access(name, AccessType.WRITE, self)
        else:
            var_info = accesses_left[self.lhs.name]
            try:
                var_info.change_read_to_write()
            except InternalError:
                # An internal error typically indicates that the same variable
                # is used twice on the LHS, e.g.: g(g(1)) = ... This is not
                # supported in PSyclone.
                from psyclone.parse.utils import ParseError
                raise ParseError(
                    "The variable '{0}' appears more than once "
                    "on the left-hand side of an assignment.".format(
                        self.lhs.name))

        # Merge the data (that shows now WRITE for the variable) with the
        # parameter to this function. It is important that first the
        # RHS is added, so that in statements like 'a=a+1' the read on
        # the RHS comes before the write on the LHS (they have the same
        # location otherwise, but the order is still important)
        self.rhs.reference_accesses(var_accesses)
        var_accesses.merge(accesses_left)
        var_accesses.next_location()
Example #26
0
    def get_output_parameters(self, node_list, variables_info=None):
        # pylint: disable=no-self-use
        '''Return all variables that are output parameters, i.e. are
        written.

        :param node_list: list of PSyIR nodes to be analysed.
        :type node_list: list of :py:class:`psyclone.psyir.nodes.Node`
        :param variables_info: optional variable usage information, \
            can be used to avoid repeatedly collecting this information.
        :type variables_info: \
            :py:class:`psyclone.core.variables_info.VariablesAccessInfo`

        :returns: a list of all variable names that are written.
        :rtype: list of str

        '''
        # Collect the information about all variables used:
        if not variables_info:
            variables_info = VariablesAccessInfo(node_list)

        return [
            var_name for var_name in variables_info.all_vars
            if variables_info.is_written(var_name)
        ]
Example #27
0
def test_indirect_addressing(parser):
    ''' Check that we correctly handle indirect addressing, especially
    on the LHS. '''
    reader = FortranStringReader('''program test_prog
                                 g(h(i)) = a
                                 end program test_prog''')
    ast = parser(reader)
    psy = PSyFactory(API).create(ast)
    schedule = psy.invokes.get("test_prog").schedule

    indirect_addressing = schedule[0]
    assert isinstance(indirect_addressing, Assignment)
    var_accesses = VariablesAccessInfo()
    indirect_addressing.reference_accesses(var_accesses)
    assert str(var_accesses) == "a: READ, g: WRITE, h: READ, i: READ"
Example #28
0
def test_lfric_stub_boundary_dofmap():
    '''Check variable usage detection in boundary_dofs array fix
    for operators.

    '''
    from psyclone.dynamo0p3 import DynKernMetadata, DynKern
    from psyclone.domain.lfric import KernStubArgList
    ast = get_ast("dynamo0.3", "enforce_operator_bc_kernel_mod.F90")
    metadata = DynKernMetadata(ast)
    kernel = DynKern()
    kernel.load_meta(metadata)
    var_accesses = VariablesAccessInfo()
    create_arg_list = KernStubArgList(kernel)
    create_arg_list.generate(var_accesses=var_accesses)
    assert "boundary_dofs_op_1: READ" in str(var_accesses)
Example #29
0
def test_goloop():
    ''' Check the handling of non-NEMO do loops.
    TODO #440: Does not work atm, GOLoops also have start/stop as
    strings, which are even not defined. Only after genCode is called will
    they be defined.
    '''

    _, invoke = get_invoke("single_invoke_two_kernels_scalars.f90",
                           "gocean1.0", name="invoke_0")
    do_loop = invoke.schedule.children[0]
    assert isinstance(do_loop, Loop)
    var_accesses = VariablesAccessInfo(do_loop)
    assert str(var_accesses) == ": READ, a_scalar: READ, i: READ+WRITE, "\
                                "j: READ+WRITE, " "ssh_fld: READ+WRITE, "\
                                "tmask: READ"
Example #30
0
def test_lfric_various_basis():
    ''' Tests that implicit parameters for various basis related
    functionality work as expected.

    '''
    _, invoke_info = get_invoke("10.3_operator_different_spaces.f90",
                                "dynamo0.3", idx=0)
    var_info = str(VariablesAccessInfo(invoke_info.schedule))
    assert "orientation_w2: READ" in var_info
    assert "basis_w3_qr: READ" in var_info
    assert "diff_basis_w0_qr: READ" in var_info
    assert "diff_basis_w2_qr: READ" in var_info
    assert "np_xy_qr: READ" in var_info
    assert "np_z_qr: READ" in var_info
    assert "weights_xy_qr: READ" in var_info
    assert "weights_z_qr: READ" in var_info