Ejemplo n.º 1
0
def test_extract_node_representation(capsys):
    ''' Test that representation properties and methods of the ExtractNode
    class: view, dag_name and __str__ produce the correct results. '''

    etrans = LFRicExtractTrans()
    _, invoke = get_invoke("4.8_multikernel_invokes.f90",
                           DYNAMO_API,
                           idx=0,
                           dist_mem=False)
    schedule = invoke.schedule
    children = schedule.children[1:3]
    etrans.apply(children)

    # Test view() method
    schedule.view()
    output, _ = capsys.readouterr()
    expected_output = colored("Extract", ExtractNode._colour)
    assert expected_output in output

    # Test dag_name method
    assert schedule.children[1].dag_name == "extract_1"

    # Test __str__ method

    assert "End DynLoop\nExtractStart[var=extract_psy_data]\nDynLoop[id:''" \
        in str(schedule)
    assert "End DynLoop\nExtractEnd[var=extract_psy_data]\nDynLoop[id:''" in \
        str(schedule)
    # Count the loops inside and outside the extract to check it is in
    # the right place
    [before, after] = str(schedule).split("ExtractStart")
    [inside, after] = after.split("ExtractEnd")
    assert before.count("Loop[") == 1
    assert inside.count("Loop[") == 2
    assert after.count("Loop[") == 2
def trans(psy):
    ''' PSyclone transformation script for the Dynamo0.3 API to
    extract the specified Kernel after applying transformations. '''

    # Get instance of the ExtractTrans transformation
    etrans = LFRicExtractTrans()

    # Import transformation script and apply transformations
    import colouring_and_omp as transformation
    psy = transformation.trans(psy)

    # Get Invoke and its Schedule
    invoke = psy.invokes.get(INVOKE_NAME)
    schedule = invoke.schedule

    # Loop over Nodes and check whether they contain the call to
    # the specified Kernel
    for child in schedule.children:
        for kernel in child.coded_kernels():
            # Extract the Node with the specified Kernel call from
            # this Invoke
            if kernel.name.lower() == KERNEL_NAME and \
              child.position == NODE_POSITION:
                print("\nExtracting Node '[" + str(child.position) +
                      "]' with Kernel call '" + KERNEL_NAME +
                      "' from Invoke '" + invoke.name + "'\n")
                etrans.apply(child)

    # Take a look at the transformed Schedule
    schedule.view()

    return psy
Ejemplo n.º 3
0
def test_no_colours_loop_dynamo0p3():
    ''' Test that applying LFRicExtractTrans on a Loop over cells
    in a colour without its parent Loop over colours in Dynamo0.3 API
    raises a TransformationError. '''

    etrans = LFRicExtractTrans()
    ctrans = Dynamo0p3ColourTrans()
    otrans = DynamoOMPParallelLoopTrans()

    _, invoke = get_invoke("1_single_invoke.f90",
                           DYNAMO_API,
                           idx=0,
                           dist_mem=False)
    schedule = invoke.schedule

    # Colour first loop that calls testkern_code (loop is over cells and
    # is not on a discontinuous space)
    ctrans.apply(schedule.children[0])
    colour_loop = schedule.children[0].loop_body[0]
    # Apply OMP Parallel DO Directive to the colour Loop
    otrans.apply(colour_loop)
    directive = schedule[0].loop_body
    # Try to extract the region between the Loop over cells in a colour
    # and the exterior Loop over colours
    with pytest.raises(TransformationError) as excinfo:
        _, _ = etrans.apply(directive)
    assert ("Dynamo0.3 API: Extraction of a Loop over cells in a "
            "colour without its ancestor Loop over colours is not "
            "allowed.") in str(excinfo.value)
Ejemplo n.º 4
0
def test_extract_node_position():
    ''' Test that Extract Transformation inserts the ExtractNode
    at the position of the first Node a Schedule in the Node list
    marked for extraction. '''

    # Test Dynamo0.3 API for extraction of a list of Nodes
    dynetrans = LFRicExtractTrans()
    _, invoke = get_invoke("15.1.2_builtin_and_normal_kernel_invoke.f90",
                           DYNAMO_API,
                           idx=0,
                           dist_mem=False)
    schedule = invoke.schedule
    # Apply Extract transformation to the first three Nodes and assert that
    # position and the absolute position of the ExtractNode are the same as
    # respective positions of the first Node before the transformation.
    pos = 0
    children = schedule.children[pos:pos + 3]
    abspos = children[0].abs_position
    dpth = children[0].depth
    dynetrans.apply(children)
    extract_node = schedule.walk(ExtractNode)
    # The result is only one ExtractNode in the list with position 0
    assert extract_node[0].position == pos
    assert extract_node[0].abs_position == abspos
    assert extract_node[0].depth == dpth
Ejemplo n.º 5
0
def test_node_list_dynamo0p3():
    ''' Test that applying Extract Transformation on a list of Nodes
    produces the correct result in the Dynamo0.3 API.

    '''
    etrans = LFRicExtractTrans()
    psy, invoke = get_invoke("15.1.2_builtin_and_normal_kernel_invoke.f90",
                             DYNAMO_API,
                             idx=0,
                             dist_mem=False)
    schedule = invoke.schedule

    etrans.apply(schedule.children[0:3])
    code = str(psy.gen)
    # This output is affected by #637 (builtin support), and needs to be
    # adjusted once this is fixed.
    output = """! ExtractStart
      !
      CALL extract_psy_data%PreStart("single_invoke_builtin_then_kernel_psy", """ \
      """"invoke_0:r0", 6, 3)
      CALL extract_psy_data%PreDeclareVariable("f2", f2)
      CALL extract_psy_data%PreDeclareVariable("f3", f3)
      CALL extract_psy_data%PreDeclareVariable("map_w2", map_w2)
      CALL extract_psy_data%PreDeclareVariable("ndf_w2", ndf_w2)
      CALL extract_psy_data%PreDeclareVariable("nlayers", nlayers)
      CALL extract_psy_data%PreDeclareVariable("undf_w2", undf_w2)
      CALL extract_psy_data%PreDeclareVariable("cell_post", cell)
      CALL extract_psy_data%PreDeclareVariable("df_post", df)
      CALL extract_psy_data%PreDeclareVariable("f3_post", f3)
      CALL extract_psy_data%PreEndDeclaration
      CALL extract_psy_data%ProvideVariable("f2", f2)
      CALL extract_psy_data%ProvideVariable("f3", f3)
      CALL extract_psy_data%ProvideVariable("map_w2", map_w2)
      CALL extract_psy_data%ProvideVariable("ndf_w2", ndf_w2)
      CALL extract_psy_data%ProvideVariable("nlayers", nlayers)
      CALL extract_psy_data%ProvideVariable("undf_w2", undf_w2)
      CALL extract_psy_data%PreEnd
      DO df=1,undf_aspc1_f5
        f5_proxy%data(df) = 0.0
      END DO
      DO df=1,undf_aspc1_f2
        f2_proxy%data(df) = 0.0
      END DO
      DO cell=1,f3_proxy%vspace%get_ncell()
        !
        CALL testkern_w2_only_code(nlayers, f3_proxy%data, """ + \
        """f2_proxy%data, ndf_w2, undf_w2, map_w2(:,cell))
      END DO
      CALL extract_psy_data%PostStart
      CALL extract_psy_data%ProvideVariable("cell_post", cell)
      CALL extract_psy_data%ProvideVariable("df_post", df)
      CALL extract_psy_data%ProvideVariable("f3_post", f3)
      CALL extract_psy_data%PostEnd
      !
      ! ExtractEnd"""
    assert output in code
Ejemplo n.º 6
0
def test_dynamo0p3_builtin():
    ''' Tests the handling of builtins.

    '''
    etrans = LFRicExtractTrans()
    psy, invoke = get_invoke("15.1.2_builtin_and_normal_kernel_invoke.f90",
                             DYNAMO_API,
                             idx=0,
                             dist_mem=False)
    schedule = invoke.schedule

    etrans.apply(schedule.children[0:3])
    code = str(psy.gen)

    output = """! ExtractStart
      !
      CALL extract_psy_data%PreStart("single_invoke_builtin_then_kernel_psy", """ \
      """"invoke_0:setval_c:r0", 4, 5)
      CALL extract_psy_data%PreDeclareVariable("map_w2", map_w2)
      CALL extract_psy_data%PreDeclareVariable("ndf_w2", ndf_w2)
      CALL extract_psy_data%PreDeclareVariable("nlayers", nlayers)
      CALL extract_psy_data%PreDeclareVariable("undf_w2", undf_w2)
      CALL extract_psy_data%PreDeclareVariable("cell_post", cell)
      CALL extract_psy_data%PreDeclareVariable("df_post", df)
      CALL extract_psy_data%PreDeclareVariable("f2_post", f2)
      CALL extract_psy_data%PreDeclareVariable("f3_post", f3)
      CALL extract_psy_data%PreDeclareVariable("f5_post", f5)
      CALL extract_psy_data%PreEndDeclaration
      CALL extract_psy_data%ProvideVariable("map_w2", map_w2)
      CALL extract_psy_data%ProvideVariable("ndf_w2", ndf_w2)
      CALL extract_psy_data%ProvideVariable("nlayers", nlayers)
      CALL extract_psy_data%ProvideVariable("undf_w2", undf_w2)
      CALL extract_psy_data%PreEnd
      DO df=1,undf_aspc1_f5
        f5_proxy%data(df) = 0.0
      END DO
      DO df=1,undf_aspc1_f2
        f2_proxy%data(df) = 0.0
      END DO
      DO cell=1,f3_proxy%vspace%get_ncell()
        !
        CALL testkern_w2_only_code(nlayers, f3_proxy%data, """ + \
        """f2_proxy%data, ndf_w2, undf_w2, map_w2(:,cell))
      END DO
      CALL extract_psy_data%PostStart
      CALL extract_psy_data%ProvideVariable("cell_post", cell)
      CALL extract_psy_data%ProvideVariable("df_post", df)
      CALL extract_psy_data%ProvideVariable("f2_post", f2)
      CALL extract_psy_data%ProvideVariable("f3_post", f3)
      CALL extract_psy_data%ProvideVariable("f5_post", f5)
      CALL extract_psy_data%PostEnd
      !
      ! ExtractEnd"""
    assert output in code
Ejemplo n.º 7
0
def test_repeat_extract():
    ''' Test that applying Extract Transformation on Node(s) already
    containing an ExtractNode raises a TransformationError. '''
    etrans = LFRicExtractTrans()

    # Test Dynamo0.3 API
    _, invoke = get_invoke("1_single_invoke.f90", DYNAMO_API,
                           idx=0, dist_mem=False)
    schedule = invoke.schedule
    # Apply Extract transformation
    schedule, _ = etrans.apply(schedule.children[0])
    # Now try applying it again on the ExtractNode
    with pytest.raises(TransformationError) as excinfo:
        _, _ = etrans.apply(schedule.children[0])
    assert ("Nodes of type 'ExtractNode' cannot be enclosed by a "
            "LFRicExtractTrans transformation") in str(excinfo.value)
Ejemplo n.º 8
0
def test_kern_builtin_no_loop():
    ''' Test that applying Extract Transformation on a Kernel or Built-in
    call without its parent Loop raises a TransformationError. '''

    # Test Dynamo0.3 API for Built-in call error
    dynetrans = LFRicExtractTrans()
    _, invoke = get_invoke("15.1.2_builtin_and_normal_kernel_invoke.f90",
                           DYNAMO_API, idx=0, dist_mem=False)
    schedule = invoke.schedule
    # Test Built-in call
    builtin_call = schedule.children[1].loop_body[0]
    with pytest.raises(TransformationError) as excinfo:
        _, _ = dynetrans.apply(builtin_call)
    assert "Error in LFRicExtractTrans: Application to a Kernel or a " \
           "Built-in call without its parent Loop is not allowed." \
           in str(excinfo.value)
Ejemplo n.º 9
0
def test_distmem_error(monkeypatch):
    ''' Test that applying ExtractRegionTrans with distributed memory
    enabled raises a TransformationError. '''
    etrans = LFRicExtractTrans()

    # Test Dynamo0.3 API with distributed memory
    _, invoke = get_invoke("1_single_invoke.f90",
                           DYNAMO_API,
                           idx=0,
                           dist_mem=True)
    schedule = invoke.schedule
    # Try applying Extract transformation
    with pytest.raises(TransformationError) as excinfo:
        _, _ = etrans.apply(schedule.children[3])
    assert ("Error in LFRicExtractTrans: Distributed memory is "
            "not supported.") in str(excinfo.value)

    # Try applying Extract transformation to Node(s) containing HaloExchange
    # We have to disable distributed memory, otherwise an earlier test
    # will be triggered
    config = Config.get()
    monkeypatch.setattr(config, "distributed_memory", False)
    with pytest.raises(TransformationError) as excinfo:
        _, _ = etrans.apply(schedule.children[2:4])
    assert ("Nodes of type 'DynHaloExchange' cannot be enclosed by a "
            "LFRicExtractTrans transformation") in str(excinfo.value)

    # Try applying Extract transformation to Node(s) containing GlobalSum
    # This will set config.distributed_mem to True again.
    _, invoke = get_invoke("15.14.3_sum_setval_field_builtin.f90",
                           DYNAMO_API,
                           idx=0,
                           dist_mem=True)
    schedule = invoke.schedule
    glob_sum = schedule.children[2]

    # We have to disable distributed memory again (get_invoke before
    # will set it to true), otherwise an earlier test will be triggered
    monkeypatch.setattr(config, "distributed_memory", False)
    with pytest.raises(TransformationError) as excinfo:
        _, _ = etrans.apply(glob_sum)

    assert ("Nodes of type 'DynGlobalSum' cannot be enclosed by a "
            "LFRicExtractTrans transformation") in str(excinfo.value)
Ejemplo n.º 10
0
def test_loop_no_directive_dynamo0p3():
    ''' Test that applying Extract Transformation on a Loop without its
    parent Directive when optimisations are applied in Dynamo0.3 API
    raises a TransformationError. '''
    etrans = LFRicExtractTrans()

    # Test a Loop nested within the OMP Parallel DO Directive
    _, invoke = get_invoke("4.13_multikernel_invokes_w3_anyd.f90",
                           DYNAMO_API, idx=0, dist_mem=False)
    schedule = invoke.schedule
    # Apply DynamoOMPParallelLoopTrans to the second Loop
    otrans = DynamoOMPParallelLoopTrans()
    schedule, _ = otrans.apply(schedule[1])
    loop = schedule.children[1].dir_body[0]
    # Try extracting the Loop inside the OMP Parallel DO region
    with pytest.raises(TransformationError) as excinfo:
        _, _ = etrans.apply(loop)
    assert "Error in LFRicExtractTrans: Application to a Loop without its " \
           "parent Directive is not allowed." in str(excinfo.value)
Ejemplo n.º 11
0
def test_extract_trans():
    '''Tests basic functions in ExtractTrans.'''
    etrans = ExtractTrans()
    assert str(etrans) == "Create a sub-tree of the PSyIR that has " \
                          "a node of type ExtractNode at its root."
    assert etrans.name == "ExtractTrans"

    ltrans = LFRicExtractTrans()
    assert str(ltrans) == "Create a sub-tree of the PSyIR that has " \
                          "a node of type ExtractNode at its root."
Ejemplo n.º 12
0
def trans(psy):
    ''' PSyclone transformation script for the Dynamo0.3 API to extract
    the specified Nodes in an Invoke. '''

    # Get instance of the ExtractTrans transformation
    etrans = LFRicExtractTrans()

    # Get Invoke and its Schedule
    invoke = psy.invokes.get(INVOKE_NAME)
    schedule = invoke.schedule

    # Apply extract transformation to selected Nodes
    print("\nExtracting Nodes '[" + str(LBOUND) + ":" + str(UBOUND) +
          "]' from Invoke '" + invoke.name + "'\n")
    etrans.apply(schedule.children[LBOUND:UBOUND])

    # Take a look at the transformed Schedule
    schedule.view()

    return psy
Ejemplo n.º 13
0
def test_node_list_error(tmpdir):
    ''' Test that applying Extract Transformation on objects which are not
    Nodes or a list of Nodes raises a TransformationError. Also raise
    transformation errors when the Nodes do not have the same parent
    if they are incorrectly ordered. '''
    etrans = LFRicExtractTrans()

    # First test for f1 readwrite to read dependency
    psy, _ = get_invoke("3.2_multi_functions_multi_named_invokes.f90",
                        DYNAMO_API,
                        idx=0,
                        dist_mem=False)
    invoke0 = psy.invokes.invoke_list[0]
    invoke1 = psy.invokes.invoke_list[1]
    # Supply an object which is not a Node or a list of Nodes
    with pytest.raises(TransformationError) as excinfo:
        etrans.apply(invoke0)
    assert ("Error in LFRicExtractTrans: Argument must be "
            "a single Node in a Schedule, a Schedule or a list of Nodes in a "
            "Schedule but have been passed an object of type: "
            "<class 'psyclone.dynamo0p3.DynInvoke'>") in str(excinfo.value)

    # Supply Nodes in incorrect order or duplicate Nodes
    node_list = [
        invoke0.schedule.children[0], invoke0.schedule.children[0],
        invoke0.schedule.children[1]
    ]
    with pytest.raises(TransformationError) as excinfo:
        etrans.apply(node_list)
    assert "Children are not consecutive children of one parent:" \
           in str(excinfo.value)
    assert "has position 0, but previous child had position 0."\
        in str(excinfo.value)

    # Supply Nodes which are not children of the same parent
    node_list = [
        invoke0.schedule.children[1], invoke1.schedule.children[0],
        invoke0.schedule.children[2]
    ]
    with pytest.raises(TransformationError) as excinfo:
        etrans.apply(node_list)
    assert ("supplied nodes are not children of the same "
            "parent.") in str(excinfo.value)

    assert LFRicBuild(tmpdir).code_compiles(psy)
Ejemplo n.º 14
0
def test_extract_colouring_omp_dynamo0p3():
    ''' Test that extraction of a Kernel in an Invoke after applying
    colouring and OpenMP optimisations produces the correct result
    in Dynamo0.3 API. '''

    const = LFRicConstants()
    etrans = LFRicExtractTrans()
    ctrans = Dynamo0p3ColourTrans()
    otrans = DynamoOMPParallelLoopTrans()

    psy, invoke = get_invoke("4.8_multikernel_invokes.f90",
                             DYNAMO_API,
                             idx=0,
                             dist_mem=False)
    schedule = invoke.schedule

    # First colour all of the loops over cells unless they are on
    # discontinuous spaces
    for child in schedule.children:
        if isinstance(child, Loop) and child.field_space.orig_name \
           not in const.VALID_DISCONTINUOUS_NAMES \
           and child.iteration_space == "cell_column":
            ctrans.apply(child)
    # Then apply OpenMP to each of the colour loops
    for child in schedule.children:
        if isinstance(child, Loop):
            if child.loop_type == "colours":
                otrans.apply(child.loop_body[0])
            else:
                otrans.apply(child)

    # Extract the second instance of ru_kernel_type after colouring
    # and OpenMP are applied
    child = schedule.children[2]
    etrans.apply(child)

    code = str(psy.gen)
    output = ("""
      ! ExtractStart
      !
      CALL extract_psy_data%PreStart("multikernel_invokes_7_psy", """
              """"invoke_0:ru_code:r0", 26, 3)
      CALL extract_psy_data%PreDeclareVariable("a", a)
      CALL extract_psy_data%PreDeclareVariable("b", b)
      CALL extract_psy_data%PreDeclareVariable("basis_w0_qr", basis_w0_qr)
      CALL extract_psy_data%PreDeclareVariable("basis_w2_qr", basis_w2_qr)
      CALL extract_psy_data%PreDeclareVariable("basis_w3_qr", basis_w3_qr)
      CALL extract_psy_data%PreDeclareVariable("c", c)
      CALL extract_psy_data%PreDeclareVariable("cmap", cmap)
      CALL extract_psy_data%PreDeclareVariable("diff_basis_w0_qr", """
              """diff_basis_w0_qr)
      CALL extract_psy_data%PreDeclareVariable("diff_basis_w2_qr", """
              """diff_basis_w2_qr)
      CALL extract_psy_data%PreDeclareVariable("e", e)
      CALL extract_psy_data%PreDeclareVariable("istp", istp)
      CALL extract_psy_data%PreDeclareVariable("map_w0", map_w0)
      CALL extract_psy_data%PreDeclareVariable("map_w2", map_w2)
      CALL extract_psy_data%PreDeclareVariable("map_w3", map_w3)
      CALL extract_psy_data%PreDeclareVariable("ndf_w0", ndf_w0)
      CALL extract_psy_data%PreDeclareVariable("ndf_w2", ndf_w2)
      CALL extract_psy_data%PreDeclareVariable("ndf_w3", ndf_w3)
      CALL extract_psy_data%PreDeclareVariable("nlayers", nlayers)
      CALL extract_psy_data%PreDeclareVariable("np_xy_qr", np_xy_qr)
      CALL extract_psy_data%PreDeclareVariable("np_z_qr", np_z_qr)
      CALL extract_psy_data%PreDeclareVariable("rdt", rdt)
      CALL extract_psy_data%PreDeclareVariable("undf_w0", undf_w0)
      CALL extract_psy_data%PreDeclareVariable("undf_w2", undf_w2)
      CALL extract_psy_data%PreDeclareVariable("undf_w3", undf_w3)
      CALL extract_psy_data%PreDeclareVariable("weights_xy_qr", weights_xy_qr)
      CALL extract_psy_data%PreDeclareVariable("weights_z_qr", weights_z_qr)
      CALL extract_psy_data%PreDeclareVariable("b_post", b)
      CALL extract_psy_data%PreDeclareVariable("cell_post", cell)
      CALL extract_psy_data%PreDeclareVariable("colour_post", colour)
      CALL extract_psy_data%PreEndDeclaration
      CALL extract_psy_data%ProvideVariable("a", a)
      CALL extract_psy_data%ProvideVariable("b", b)
      CALL extract_psy_data%ProvideVariable("basis_w0_qr", basis_w0_qr)
      CALL extract_psy_data%ProvideVariable("basis_w2_qr", basis_w2_qr)
      CALL extract_psy_data%ProvideVariable("basis_w3_qr", basis_w3_qr)
      CALL extract_psy_data%ProvideVariable("c", c)
      CALL extract_psy_data%ProvideVariable("cmap", cmap)
      CALL extract_psy_data%ProvideVariable("diff_basis_w0_qr", """
              """diff_basis_w0_qr)
      CALL extract_psy_data%ProvideVariable("diff_basis_w2_qr", """
              """diff_basis_w2_qr)
      CALL extract_psy_data%ProvideVariable("e", e)
      CALL extract_psy_data%ProvideVariable("istp", istp)
      CALL extract_psy_data%ProvideVariable("map_w0", map_w0)
      CALL extract_psy_data%ProvideVariable("map_w2", map_w2)
      CALL extract_psy_data%ProvideVariable("map_w3", map_w3)
      CALL extract_psy_data%ProvideVariable("ndf_w0", ndf_w0)
      CALL extract_psy_data%ProvideVariable("ndf_w2", ndf_w2)
      CALL extract_psy_data%ProvideVariable("ndf_w3", ndf_w3)
      CALL extract_psy_data%ProvideVariable("nlayers", nlayers)
      CALL extract_psy_data%ProvideVariable("np_xy_qr", np_xy_qr)
      CALL extract_psy_data%ProvideVariable("np_z_qr", np_z_qr)
      CALL extract_psy_data%ProvideVariable("rdt", rdt)
      CALL extract_psy_data%ProvideVariable("undf_w0", undf_w0)
      CALL extract_psy_data%ProvideVariable("undf_w2", undf_w2)
      CALL extract_psy_data%ProvideVariable("undf_w3", undf_w3)
      CALL extract_psy_data%ProvideVariable("weights_xy_qr", weights_xy_qr)
      CALL extract_psy_data%ProvideVariable("weights_z_qr", weights_z_qr)
      CALL extract_psy_data%PreEnd
      DO colour=1,ncolour
        !$omp parallel do default(shared), private(cell), schedule(static)
        DO cell=1,mesh%get_last_edge_cell_per_colour(colour)
          !
          CALL ru_code(nlayers, b_proxy%data, a_proxy%data, istp, rdt, """
              "c_proxy%data, e_proxy(1)%data, e_proxy(2)%data, "
              "e_proxy(3)%data, ndf_w2, undf_w2, "
              "map_w2(:,cmap(colour, cell)), "
              "basis_w2_qr, diff_basis_w2_qr, ndf_w3, undf_w3, "
              "map_w3(:,cmap(colour, cell)), basis_w3_qr, ndf_w0, undf_w0, "
              "map_w0(:,cmap(colour, cell)), basis_w0_qr, diff_basis_w0_qr, "
              """np_xy_qr, np_z_qr, weights_xy_qr, weights_z_qr)
        END DO
        !$omp end parallel do
      END DO
      CALL extract_psy_data%PostStart
      CALL extract_psy_data%ProvideVariable("b_post", b)
      CALL extract_psy_data%ProvideVariable("cell_post", cell)
      CALL extract_psy_data%ProvideVariable("colour_post", colour)
      CALL extract_psy_data%PostEnd
      !
      ! ExtractEnd""")
    assert output in code
Ejemplo n.º 15
0
def test_extract_kernel_and_builtin_dynamo0p3():
    ''' Test that extraction of a Kernel and a BuiltIny in an Invoke
    produces the correct result in Dynamo0.3 API.

    '''
    etrans = LFRicExtractTrans()

    psy, invoke = get_invoke("15.1.2_builtin_and_normal_kernel_invoke.f90",
                             DYNAMO_API,
                             idx=0,
                             dist_mem=False)
    schedule = invoke.schedule

    etrans.apply(schedule.children[1:3])
    code = str(psy.gen)
    output = """
      ! ExtractStart
      !
      CALL extract_psy_data%PreStart("single_invoke_builtin_then_kernel_psy", """ \
      """"invoke_0:r0", 6, 3)
      CALL extract_psy_data%PreDeclareVariable("f2", f2)
      CALL extract_psy_data%PreDeclareVariable("f3", f3)
      CALL extract_psy_data%PreDeclareVariable("map_w2", map_w2)
      CALL extract_psy_data%PreDeclareVariable("ndf_w2", ndf_w2)
      CALL extract_psy_data%PreDeclareVariable("nlayers", nlayers)
      CALL extract_psy_data%PreDeclareVariable("undf_w2", undf_w2)
      CALL extract_psy_data%PreDeclareVariable("cell_post", cell)
      CALL extract_psy_data%PreDeclareVariable("df_post", df)
      CALL extract_psy_data%PreDeclareVariable("f3_post", f3)
      CALL extract_psy_data%PreEndDeclaration
      CALL extract_psy_data%ProvideVariable("f2", f2)
      CALL extract_psy_data%ProvideVariable("f3", f3)
      CALL extract_psy_data%ProvideVariable("map_w2", map_w2)
      CALL extract_psy_data%ProvideVariable("ndf_w2", ndf_w2)
      CALL extract_psy_data%ProvideVariable("nlayers", nlayers)
      CALL extract_psy_data%ProvideVariable("undf_w2", undf_w2)
      CALL extract_psy_data%PreEnd
      DO df=1,undf_aspc1_f2
        f2_proxy%data(df) = 0.0
      END DO
      DO cell=1,f3_proxy%vspace%get_ncell()
        !
        CALL testkern_w2_only_code(nlayers, f3_proxy%data, """ + \
        """f2_proxy%data, ndf_w2, undf_w2, map_w2(:,cell))
      END DO
      CALL extract_psy_data%PostStart
      CALL extract_psy_data%ProvideVariable("cell_post", cell)
      CALL extract_psy_data%ProvideVariable("df_post", df)
      CALL extract_psy_data%ProvideVariable("f3_post", f3)
      CALL extract_psy_data%PostEnd
      !
      ! ExtractEnd"""

    assert output in code

    # TODO #706: Compilation for LFRic extraction not supported yet.
    # assert LFRicBuild(tmpdir).code_compiles(psy)

    # TODO #637 (no builtin support)
    # This is an excerpt of missing lines, which will cause this test to x-fail
    not_yet_working = [
        'CALL extract_psy_data%PreDeclareVariable("f2_post", '
        'f2)', 'CALL extract_psy_data%ProvideVariable("f2_post", f2)'
    ]
    for line in not_yet_working:
        if line not in code:
            pytest.xfail("#637 LFRic builtin not supported yet.")
    assert False, "X-failing test suddenly working: #637 LFRic builtin."
Ejemplo n.º 16
0
def test_extract_single_builtin_dynamo0p3():
    ''' Test that extraction of a BuiltIn in an Invoke produces the
    correct result in Dynamo0.3 API without and with optimisations.

    '''
    etrans = LFRicExtractTrans()

    otrans = DynamoOMPParallelLoopTrans()

    psy, invoke = get_invoke("15.1.2_builtin_and_normal_kernel_invoke.f90",
                             DYNAMO_API,
                             idx=0,
                             dist_mem=False)
    schedule = invoke.schedule

    etrans.apply(schedule.children[1])
    code = str(psy.gen)
    output = """! ExtractStart
      !
      CALL extract_psy_data%PreStart("single_invoke_builtin_then_kernel_psy", """ \
      """"invoke_0:setval_c:r0", 0, 1)
      CALL extract_psy_data%PreDeclareVariable("df_post", df)
      CALL extract_psy_data%PreEndDeclaration
      CALL extract_psy_data%PreEnd
      DO df=1,undf_aspc1_f2
        f2_proxy%data(df) = 0.0
      END DO
      CALL extract_psy_data%PostStart
      CALL extract_psy_data%ProvideVariable("df_post", df)
      CALL extract_psy_data%PostEnd
      !
      ! ExtractEnd"""

    assert output in code

    # Test extract with OMP Parallel optimisation
    psy, invoke = get_invoke("15.1.1_builtin_and_normal_kernel_invoke_2.f90",
                             DYNAMO_API,
                             idx=0,
                             dist_mem=False)
    schedule = invoke.schedule

    otrans.apply(schedule.children[1])
    etrans.apply(schedule.children[1])
    code_omp = str(psy.gen)
    output = """
      ! ExtractStart
      !
      CALL extract_psy_data%PreStart("single_invoke_psy", """ \
      """"invoke_0:inc_ax_plus_y:r0", 0, 1)
      CALL extract_psy_data%PreDeclareVariable("df_post", df)
      CALL extract_psy_data%PreEndDeclaration
      CALL extract_psy_data%PreEnd
      !$omp parallel do default(shared), private(df), schedule(static)
      DO df=1,undf_aspc1_f1
        f1_proxy%data(df) = 0.5_r_def*f1_proxy%data(df) + f2_proxy%data(df)
      END DO
      !$omp end parallel do
      CALL extract_psy_data%PostStart
      CALL extract_psy_data%ProvideVariable("df_post", df)
      CALL extract_psy_data%PostEnd
      !
      ! ExtractEnd"""
    assert output in code_omp

    # TODO #637 (no builtin support)
    # Builtins are not yet support, so some arguments are missing. This
    # is an excerpt of missing lines, which will cause this test to x-fail
    not_yet_working = [
        'CALL extract_psy_data%ProvideVariable("f1", f1)',
        'CALL extract_psy_data%ProvideVariable("f2", f2)'
    ]
    for line in not_yet_working:
        if line not in code:
            pytest.xfail("#637 LFRic builtins are not supported yet.")
        if line not in code_omp:
            pytest.xfail("#637 LFRic builtins are not supported yet.")
    assert False, "X-failing test suddenly working: #637 lfric builtins."
Ejemplo n.º 17
0
def test_single_node_dynamo0p3():
    ''' Test that Extract Transformation on a single Node in a Schedule
    produces the correct result in Dynamo0.3 API. '''
    etrans = LFRicExtractTrans()

    psy, invoke = get_invoke("1_single_invoke.f90",
                             DYNAMO_API,
                             idx=0,
                             dist_mem=False)
    schedule = invoke.schedule

    etrans.apply(schedule.children[0])
    code = str(psy.gen)
    output = """      ! ExtractStart
      !
      CALL extract_psy_data%PreStart("single_invoke_psy", "invoke_0_testkern""" \
      """_type:testkern_code:r0", 15, 2)
      CALL extract_psy_data%PreDeclareVariable("a", a)
      CALL extract_psy_data%PreDeclareVariable("f1", f1)
      CALL extract_psy_data%PreDeclareVariable("f2", f2)
      CALL extract_psy_data%PreDeclareVariable("m1", m1)
      CALL extract_psy_data%PreDeclareVariable("m2", m2)
      CALL extract_psy_data%PreDeclareVariable("map_w1", map_w1)
      CALL extract_psy_data%PreDeclareVariable("map_w2", map_w2)
      CALL extract_psy_data%PreDeclareVariable("map_w3", map_w3)
      CALL extract_psy_data%PreDeclareVariable("ndf_w1", ndf_w1)
      CALL extract_psy_data%PreDeclareVariable("ndf_w2", ndf_w2)
      CALL extract_psy_data%PreDeclareVariable("ndf_w3", ndf_w3)
      CALL extract_psy_data%PreDeclareVariable("nlayers", nlayers)
      CALL extract_psy_data%PreDeclareVariable("undf_w1", undf_w1)
      CALL extract_psy_data%PreDeclareVariable("undf_w2", undf_w2)
      CALL extract_psy_data%PreDeclareVariable("undf_w3", undf_w3)
      CALL extract_psy_data%PreDeclareVariable("cell_post", cell)
      CALL extract_psy_data%PreDeclareVariable("f1_post", f1)
      CALL extract_psy_data%PreEndDeclaration
      CALL extract_psy_data%ProvideVariable("a", a)
      CALL extract_psy_data%ProvideVariable("f1", f1)
      CALL extract_psy_data%ProvideVariable("f2", f2)
      CALL extract_psy_data%ProvideVariable("m1", m1)
      CALL extract_psy_data%ProvideVariable("m2", m2)
      CALL extract_psy_data%ProvideVariable("map_w1", map_w1)
      CALL extract_psy_data%ProvideVariable("map_w2", map_w2)
      CALL extract_psy_data%ProvideVariable("map_w3", map_w3)
      CALL extract_psy_data%ProvideVariable("ndf_w1", ndf_w1)
      CALL extract_psy_data%ProvideVariable("ndf_w2", ndf_w2)
      CALL extract_psy_data%ProvideVariable("ndf_w3", ndf_w3)
      CALL extract_psy_data%ProvideVariable("nlayers", nlayers)
      CALL extract_psy_data%ProvideVariable("undf_w1", undf_w1)
      CALL extract_psy_data%ProvideVariable("undf_w2", undf_w2)
      CALL extract_psy_data%ProvideVariable("undf_w3", undf_w3)
      CALL extract_psy_data%PreEnd
      DO cell=1,f1_proxy%vspace%get_ncell()
        !
        CALL testkern_code(nlayers, a, f1_proxy%data, f2_proxy%data, """ + \
        "m1_proxy%data, m2_proxy%data, ndf_w1, undf_w1, " + \
        "map_w1(:,cell), ndf_w2, undf_w2, map_w2(:,cell), ndf_w3, " + \
        """undf_w3, map_w3(:,cell))
      END DO
      CALL extract_psy_data%PostStart
      CALL extract_psy_data%ProvideVariable("cell_post", cell)
      CALL extract_psy_data%ProvideVariable("f1_post", f1)
      CALL extract_psy_data%PostEnd
      !
      ! ExtractEnd"""
    assert output in code