def test_scalar_invoke_uniq_declns_valid_intrinsic(): ''' Tests that all valid intrinsic types for user-defined scalar arguments ('real', 'integer' and 'logical') are accepted by Invoke.unique_declarations(). ''' _, invoke_info = parse(os.path.join(BASE_PATH, "1.7_single_invoke_3scalar.f90"), api=TEST_API) psy = PSyFactory(TEST_API, distributed_memory=False).create(invoke_info) invoke = psy.invokes.invoke_list[0] # Test 'real' scalars const = LFRicConstants() scalars_real_args = invoke.unique_declarations(const.VALID_SCALAR_NAMES, intrinsic_type="real") scalars_real = [arg.declaration_name for arg in scalars_real_args] assert scalars_real == ["a"] # Test 'integer' scalars scalars_integer_args = invoke.unique_declarations(const.VALID_SCALAR_NAMES, intrinsic_type="integer") scalars_integer = [arg.declaration_name for arg in scalars_integer_args] assert scalars_integer == ["istep"] # Test 'logical' scalars scalars_logical_args = invoke.unique_declarations(const.VALID_SCALAR_NAMES, intrinsic_type="logical") scalars_logical = [arg.declaration_name for arg in scalars_logical_args] assert scalars_logical == ["lswitch"]
def test_ad_scalar_type_no_inc(): ''' Tests that an error is raised when the argument descriptor metadata for a scalar specifies 'GH_INC' access. ''' fparser.logging.disable(fparser.logging.CRITICAL) name = "testkern_qr_type" const = LFRicConstants() for argname in const.VALID_SCALAR_NAMES: code = CODE.replace("arg_type(" + argname + ", gh_real, gh_read)", "arg_type(" + argname + ", gh_real, gh_inc)", 1) ast = fpapi.parse(code, ignore_comments=False) with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert ("scalar arguments must have read-only ('gh_read') or a " "reduction ['gh_sum'] access but found 'gh_inc'" in str(excinfo.value))
def test_ad_scalar_invalid_data_type(): ''' Tests that an error is raised when the argument descriptor metadata for a scalar has an invalid data type. ''' fparser.logging.disable(fparser.logging.CRITICAL) name = "testkern_qr_type" code = CODE.replace("arg_type(gh_scalar, gh_real, gh_read)", "arg_type(gh_scalar, gh_unreal, gh_read)", 1) ast = fpapi.parse(code, ignore_comments=False) const = LFRicConstants() with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert ("In the LFRic API the 2nd argument of a 'meta_arg' entry should " "be a valid data type (one of {0}), but found 'gh_unreal' in " "'arg_type(gh_scalar, gh_unreal, gh_read)'.".format( const.VALID_SCALAR_DATA_TYPES) in str(excinfo.value))
def test_no_vector_scalar(): ''' Tests that we raise an error when kernel metadata erroneously specifies a vector scalar argument. ''' fparser.logging.disable(fparser.logging.CRITICAL) name = "testkern_qr_type" const = LFRicConstants() for argname in const.VALID_SCALAR_NAMES: vectname = argname + " * 3" code = CODE.replace("arg_type(" + argname + ", gh_real, gh_read)", "arg_type(" + vectname + ", gh_real, gh_read)", 1) ast = fpapi.parse(code, ignore_comments=False) with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert ("vector notation is only supported for ['gh_field'] " "argument types but found '{0}'".format(vectname) in str(excinfo.value))
def test_scalar_different_data_types_invoke(): ''' Tests that the same scalar cannot have different data types in different kernels within the same Invoke. ''' _, invoke_info = parse(os.path.join( BASE_PATH, "4.16_multikernel_invokes_real_int_scalar_invalid.f90"), api=TEST_API) psy = PSyFactory(TEST_API, distributed_memory=False).create(invoke_info) const = LFRicConstants() with pytest.raises(GenerationError) as excinfo: _ = psy.gen assert ("Scalar argument(s) ['b'] in Invoke " "'invoke_real_and_integer_scalars' have different metadata for " "data type ({0}) in different kernels. This is invalid.".format( const.VALID_SCALAR_DATA_TYPES) in str(excinfo.value))
def test_ad_scalar_type_too_many_args(): ''' Tests that an error is raised when the argument descriptor metadata for a scalar has more than 3 args. ''' fparser.logging.disable(fparser.logging.CRITICAL) name = "testkern_qr_type" const = LFRicConstants() for argname in const.VALID_SCALAR_NAMES: code = CODE.replace( "arg_type(" + argname + ", gh_integer, gh_read)", "arg_type(" + argname + ", gh_integer, gh_read, w1)", 1) ast = fpapi.parse(code, ignore_comments=False) with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert ("each 'meta_arg' entry must have 3 arguments if its first " "argument is 'gh_scalar', but found 4 in " "'arg_type(gh_scalar, gh_integer, gh_read, w1)'." in str(excinfo.value))
def test_ad_scalar_type_too_few_args(): ''' Tests that an error is raised when the argument descriptor metadata for a scalar has fewer than 3 args. Note: This general check is also valid for all other argument types. ''' fparser.logging.disable(fparser.logging.CRITICAL) name = "testkern_qr_type" const = LFRicConstants() for argname in const.VALID_SCALAR_NAMES: code = CODE.replace("arg_type(" + argname + ", gh_real, gh_read)", "arg_type(" + argname + ", gh_real)", 1) ast = fpapi.parse(code, ignore_comments=False) with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert ("In the LFRic API each 'meta_arg' entry must have at least " "3 args, but found 2 in 'arg_type(gh_scalar, gh_real)'." in str(excinfo.value))
def test_ad_scalar_init_wrong_data_type(monkeypatch): ''' Test that an error is raised if an invalid data type is passed to the LFRicArgDescriptor._init_scalar() method. ''' ast = fpapi.parse(CODE, ignore_comments=False) name = "testkern_qr_type" metadata = DynKernMetadata(ast, name=name) # Get a scalar argument descriptor and set a wrong data type scalar_arg = metadata._inits[0] scalar_arg.args[1].name = "gh_double" const = LFRicConstants() # Now try to trip the error by making the initial test think # that 'gh_double' is actually a valid data type monkeypatch.setattr(target=LFRicConstants, name="VALID_ARG_DATA_TYPES", value=LFRicConstants.VALID_ARG_DATA_TYPES + ["gh_double"]) with pytest.raises(InternalError) as excinfo: LFRicArgDescriptor(scalar_arg, metadata.iterates_over)._init_scalar(scalar_arg) assert ("Expected one of {0} as the scalar data type but got 'gh_double'.". format(const.VALID_SCALAR_DATA_TYPES) in str(excinfo.value))