Exemple #1
0
def test_constructor(fortran_reader):
    '''Test the optional constructor parameter (single node and list
    of nodes).'''
    code = '''module test
        contains
        subroutine tmp()
          integer :: a,b,c
          a = b/c
          c = a*b
        end subroutine tmp
        end module test'''
    psyir = fortran_reader.psyir_from_source(code)
    schedule = psyir.children[0].children[0]
    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)
Exemple #2
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
    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
Exemple #3
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[Signature("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].component_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[Signature("p_fld")]
    all_indices = [access.component_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
    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:
        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}

        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, ""))
Exemple #5
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.
    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
Exemple #6
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 signatures that are read.
        :rtype: list of :py:class:`psyclone.core.Signature`

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

        input_list = []
        for signature in variables_info.all_signatures:
            # 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[signature][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(signature)

        return input_list
Exemple #7
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[Signature("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
Exemple #8
0
def test_lfric_acc():
    '''Check variable usage detection when OpenACC is used.

    '''
    # Use the OpenACC transforms to enclose the kernels
    # with OpenACC directives.
    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
Exemple #9
0
def test_derived_type_array(array, indices, fortran_writer, fortran_reader):
    '''This function tests the handling of derived array types.
    '''
    code = '''module test
        contains
        subroutine tmp()
          use my_mod
          !use my_mod, only: something
          !type(something) :: a, b, c
          integer :: i, j, k
          c(i)%e(j,k) = {0}
        end subroutine tmp
        end module test'''.format(array)

    schedule = fortran_reader.psyir_from_source(code).children[0]
    node1 = schedule.children[0][0]
    vai1 = VariablesAccessInfo(node1)
    assert isinstance(node1, Assignment)
    assert str(vai1) == "a%b%c: READ, c%e: WRITE, i: READ, j: READ, k: READ"

    # Verify that the index expression is correct. Convert the index
    # expression to a list of list of strings to make this easier:
    sig = Signature(("a", "b", "c"))
    access = vai1[sig][0]
    assert to_fortran(fortran_writer, access.component_indices) == indices
Exemple #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
Exemple #11
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
Exemple #12
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
Exemple #13
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
Exemple #14
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
Exemple #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
Exemple #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
Exemple #17
0
def test_symbol_array_detection(fortran_reader):
    '''Verifies the handling of arrays together with access information.
    '''

    code = '''program test_prog
              use some_mod
              real, dimension(5,5) :: b, c
              integer :: i
              a = b(i) + c
              end program test_prog'''
    psyir = fortran_reader.psyir_from_source(code)
    scalar_assignment = psyir.children[0]
    symbol_table = scalar_assignment.scope.symbol_table
    sym_a = symbol_table.lookup("a")
    with pytest.raises(InternalError) as error:
        sym_a.is_array_access(index_variable="j")
    assert "In Symbol.is_array_access: index variable 'j' specified, but " \
           "no access information given." in str(error.value)

    vai = VariablesAccessInfo()
    scalar_assignment.reference_accesses(vai)

    # For 'a' we don't have access information, nor symbol table information
    access_info_a = vai[Signature("a")]
    with pytest.raises(ValueError) as error:
        sym_a.is_array_access(access_info=access_info_a)
    assert "No array information is available for the symbol 'a'" \
        in str(error.value)

    # For the access to 'b' we will find array access information:
    access_info_b = vai[Signature("b")]
    sym_b = symbol_table.lookup("b")
    b_is_array = sym_b.is_array_access(access_info=access_info_b)
    assert b_is_array

    # For the access to 'c' we don't have access information, but
    # have symbol table information.
    access_info_c = vai[Signature("c")]
    sym_c = symbol_table.lookup("c")
    c_is_array = sym_c.is_array_access(access_info=access_info_c)
    assert c_is_array

    # Test specifying the index variable. The access to 'b' is
    # considered an array access when ysing the index variable 'i'.
    access_info_b = vai[Signature("b")]
    sym_b = symbol_table.lookup("b")
    b_is_array = sym_b.is_array_access(access_info=access_info_b,
                                       index_variable="i")
    assert b_is_array

    # Verify that the access to 'b' is not considered to be an
    # array access regarding the loop variable 'j' (the access
    # is loop independent):
    b_is_array = sym_b.is_array_access(access_info=access_info_b,
                                       index_variable="j")
    assert not b_is_array
Exemple #18
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
Exemple #19
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)
Exemple #20
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 [str(signature) for signature in variables_info.all_signatures
                if variables_info.is_written(signature)]
Exemple #21
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
def test_reference_accesses():
    ''' Test the reference_accesses method.
    '''
    dref = nodes.StructureReference.create(
        symbols.DataSymbol(
            "grid", symbols.DataTypeSymbol("grid_type",
                                           symbols.DeferredType())), ["data"])
    var_access_info = VariablesAccessInfo()
    dref.reference_accesses(var_access_info)

    assert var_access_info.all_signatures == [Signature(("grid", "data"))]
    # By default all accesses are marked as read
    assert str(var_access_info) == "grid%data: READ"
Exemple #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
Exemple #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"
Exemple #25
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 gen_code() 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"
Exemple #26
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 "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
Exemple #27
0
def test_indirect_addressing(parser):
    ''' Check that we correctly handle indirect addressing, especially
    on the LHS. '''
    reader = FortranStringReader('''program test_prog
                                 integer :: i, h(10)
                                 real :: a, g(10)
                                 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)
    assert str(var_accesses) == "a: READ, g: WRITE, h: READ, i: READ"
Exemple #28
0
    def get_in_out_parameters(self, node_list):
        '''Return a 2-tuple of lists that contains all variables that are input
        parameters (first entry) and output parameters (second entry).
        This function calls get_input_parameter and get_output_parameter,
        but avoids the repeated computation of the variable usage.

        :param node_list: list of PSyIR nodes to be analysed.
        :type node_list: list of :py:class:`psyclone.psyir.nodes.Node`

        :returns: a 2-tuple of two lists, the first one containing \
            the input parameters, the second the output paramters.
        :rtype: 2-tuple of list of :py:class:`psyclone.core.Signature`

        '''
        variables_info = VariablesAccessInfo(node_list)
        return (self.get_input_parameters(node_list, variables_info),
                self.get_output_parameters(node_list, variables_info))
Exemple #29
0
def test_user_defined_variables(parser):
    ''' Test reading and writing to user defined variables.
    '''
    reader = FortranStringReader('''program test_prog
                                       use some_mod, only: my_type
                                       type(my_type) :: a, e
                                       integer :: ji, jj, d
                                       a%b(ji)%c(ji, jj) = d
                                       e%f = d
                                    end program test_prog''')
    prog = parser(reader)
    psy = PSyFactory("nemo", distributed_memory=False).create(prog)
    loops = psy.invokes.get("test_prog").schedule

    var_accesses = VariablesAccessInfo(loops)
    assert var_accesses[Signature(("a", "b", "c"))].is_written
    assert var_accesses[Signature(("e", "f"))].is_written
Exemple #30
0
def test_lfric_stub_args3():
    '''Check variable usage detection for cell position, operator

    '''
    ast = get_ast("dynamo0.3", "testkern_any_discontinuous_space_op_1_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 "cell: READ" in var_info
    assert "op_3: READ" in var_info
    assert "op_3_ncell_3d: READ" in var_info
    assert "op_4: READ" in var_info
    assert "op_4_ncell_3d: READ" in var_info