def test_apply_mixed(fortran_reader): '''Test that an invoke with a mixture of kernels and builtins, with a number of the kernels and an optional name being within a single codeblock, are translated into an LFRicBuiltinFunctor and expected children. ''' code = ( "subroutine alg()\n" " use kern_mod\n" " use field_mod, only : field\n" " type(field) :: field1\n" " integer :: value\n" " call invoke(kern(field1), setval_c(field1, 1.0), name='test', " "setval_c(field1, 1.0), setval_c(field1, value))\n" "end subroutine alg\n") psyir = fortran_reader.psyir_from_source(code) lfric_invoke_trans = LFRicInvokeCallTrans() lfric_invoke_trans.apply(psyir[0], 5) check_invoke( psyir[0], [(LFRicKernelFunctor, "kern"), (LFRicBuiltinFunctor, "setval_c"), (LFRicBuiltinFunctor, "setval_c"), (LFRicBuiltinFunctor, "setval_c")], description="test") args = psyir[0].children[0].children check_args(args, [(Reference, "field1")]) args = psyir[0].children[1].children check_args(args, [(Reference, "field1"), (Literal, "1.0")]) args = psyir[0].children[2].children check_args(args, [(Reference, "field1"), (Literal, "1.0")]) args = psyir[0].children[3].children check_args(args, [(Reference, "field1"), (Reference, "value")])
def test_apply_codedkern_arrayref(fortran_reader): '''Test that a kernel call within an invoke that is mistakenly encoded as an ArrayRef in the PSyIR is translated into an LFRicKernelFunctor and expected children. This test also checks that an optional name is captured correctly. Also checks that the index argument is captured correctly. ''' code = ( "subroutine alg()\n" " use kern_mod\n" " use field_mod, only : field\n" " type(field) :: field1\n" " call invoke(kern(field1), name='hello')\n" "end subroutine alg\n") psyir = fortran_reader.psyir_from_source(code) lfric_invoke_trans = LFRicInvokeCallTrans() lfric_invoke_trans.apply(psyir[0], 1) check_invoke(psyir[0], [(LFRicKernelFunctor, "kern")], description="hello") assert psyir[0]._index == 1 args = psyir[0].children[0].children check_args(args, [(Reference, "field1")])
def test_apply_builtin_arrayref(fortran_reader): '''Test that a builtin call within an invoke that is mistakenly encoded as an ArrayRef in the PSyIR is translated into an LFRicBuiltinFunctor and expected children. This test also checks that an optional name is captured correctly. ''' code = ( "subroutine alg()\n" " use kern_mod\n" " use field_mod, only : field\n" " type(field) :: field1\n" " integer :: value\n" " call invoke(setval_c(field1, value), name='test')\n" "end subroutine alg\n") psyir = fortran_reader.psyir_from_source(code) lfric_invoke_trans = LFRicInvokeCallTrans() lfric_invoke_trans.apply(psyir[0], 4) check_invoke(psyir[0], [(LFRicBuiltinFunctor, "setval_c")], description="test") args = psyir[0].children[0].children check_args(args, [(Reference, "field1"), (Reference, "value")])
def test_codeblock_invalid(monkeypatch, fortran_reader): '''Test that the expected exception is raised if unsupported content is found within a codeblock. Use monkeypatch to sabotage the codeblock to cause the exception. ''' code = ( "subroutine alg()\n" " use kern_mod\n" " call invoke(name='tallulah')\n" "end subroutine alg\n") psyir = fortran_reader.psyir_from_source(code) subroutine = psyir.children[0] code_block = subroutine[0].children[0] assert isinstance(code_block, CodeBlock) monkeypatch.setattr(code_block, "_fp2_nodes", [None]) lfric_invoke_trans = LFRicInvokeCallTrans() with pytest.raises(TransformationError) as info: lfric_invoke_trans.validate(subroutine[0]) assert ("Expecting an algorithm invoke codeblock to contain either " "Structure-Constructor or actual-arg-spec, but found " "'NoneType'." in str(info.value))
def test_init(): '''Check that an LFRicInvokeCallTrans instance can be created correctly, has the expected defaults, deals with any __init__ arguments and its name method returns the expected value. ''' invoke_trans = LFRicInvokeCallTrans() assert invoke_trans.name == "LFRicInvokeCallTrans" assert isinstance(invoke_trans, LFRicInvokeCallTrans)
def test_multi_named_arg_error(fortran_reader): '''Test that the validation method raises an exception if more than one named argument is specified in an invoke call. Also check that the apply method calls the validate method. ''' code = ( "subroutine alg()\n" " use kern_mod\n" " call invoke(name='first', name='second')\n" "end subroutine alg\n") psyir = fortran_reader.psyir_from_source(code) lfric_invoke_trans = LFRicInvokeCallTrans() with pytest.raises(TransformationError) as info: lfric_invoke_trans.validate(psyir[0]) assert ("Error in LFRicInvokeCallTrans transformation. There should be at " "most one named argument in an invoke, but there are at least " "two: 'first' and 'second'." in str(info.value)) with pytest.raises(TransformationError) as info: lfric_invoke_trans.apply(psyir[0], 0) assert ("Error in LFRicInvokeCallTrans transformation. There should be at " "most one named argument in an invoke, but there are at least " "two: 'first' and 'second'." in str(info.value))
def test_named_arg_error(string, fortran_reader): '''Test that the validation method raises an exception if a named argument has an unsupported format. ''' code = ( "subroutine alg()\n" " use kern_mod\n" " call invoke({0})\n" "end subroutine alg\n".format(string)) psyir = fortran_reader.psyir_from_source(code) lfric_invoke_trans = LFRicInvokeCallTrans() with pytest.raises(TransformationError) as info: lfric_invoke_trans.validate(psyir[0]) assert ("Error in LFRicInvokeCallTrans transformation. If there is a " "named argument, it must take the form name='str', but found " "'{0}'.".format(string) in str(info.value)) with pytest.raises(TransformationError) as info: lfric_invoke_trans._validate_fp2_node( psyir[0].children[0]._fp2_nodes[0]) assert ("Error in LFRicInvokeCallTrans transformation. If there is a " "named argument, it must take the form name='str', but found " "'{0}'.".format(string) in str(info.value))
def test_apply_codedkern_structconstruct(fortran_reader): '''Test that a kernel call within an invoke that is encoded within a PSyIR code block as an fparser2 Structure Constructor is translated into an LFRicKernelFunctor and expected children. ''' code = ( "subroutine alg()\n" " use kern_mod\n" " use field_mod, only : field\n" " type(field) :: field1\n" " call invoke(kern(1.0))\n" "end subroutine alg\n") psyir = fortran_reader.psyir_from_source(code) lfric_invoke_trans = LFRicInvokeCallTrans() lfric_invoke_trans.apply(psyir[0], 2) check_invoke(psyir[0], [(LFRicKernelFunctor, "kern")]) args = psyir[0].children[0].children check_args(args, [(Literal, "1.0")])
def test_apply_builtin_structconstruct(fortran_reader): '''Test that a builtin call within an invoke that is encoded within a PSyIR code block as an fparser2 Structure Constructor is translated into an LFRicBuiltinFunctor and expected children. This test also checks that an optional name is captured correctly. ''' code = ( "subroutine alg()\n" " use kern_mod\n" " use field_mod, only : field\n" " type(field) :: field1\n" " call invoke(setval_c(field1, 1.0))\n" "end subroutine alg\n") psyir = fortran_reader.psyir_from_source(code) lfric_invoke_trans = LFRicInvokeCallTrans() lfric_invoke_trans.apply(psyir[0], 3) check_invoke(psyir[0], [(LFRicBuiltinFunctor, "setval_c")]) args = psyir[0].children[0].children check_args(args, [(Reference, "field1"), (Literal, "1.0")])
def test_structure_contructor(fortran_reader): '''Test that validation does not raise an exception if the fparser2 node is a structure constructor. ''' code = ( "subroutine alg()\n" " use kern_mod\n" " call invoke(kern(1.0))\n" "end subroutine alg\n") psyir = fortran_reader.psyir_from_source(code) lfric_invoke_trans = LFRicInvokeCallTrans() lfric_invoke_trans.validate(psyir[0]) lfric_invoke_trans._validate_fp2_node( psyir[0].children[0]._fp2_nodes[0])
def __init__(self): super(LFRicAlgTrans, self).__init__() self._invoke_trans = LFRicInvokeCallTrans()