Exemple #1
0
    def _init_scalar(self, arg_type):
        '''
        Validates metadata descriptors for scalar arguments and
        initialises scalar argument properties accordingly.

        :param arg_type: LFRic API scalar argument type.
        :type arg_type: :py:class:`psyclone.expression.FunctionVar`

        :raises InternalError: if argument type other than a scalar is \
                               passed in.
        :raises ParseError: if there are not exactly 3 metadata arguments.
        :raises InternalError: if a scalar argument has an invalid data type.
        :raises ParseError: if scalar arguments do not have a read-only or
                            a reduction access.
        :raises ParseError: if a scalar argument that is not a real \
                            scalar has a reduction access.

        '''
        # Check whether something other than a scalar is passed in
        if self._argument_type not in LFRicArgDescriptor.VALID_SCALAR_NAMES:
            raise InternalError(
                "LFRicArgDescriptor._init_scalar(): expected a scalar "
                "argument but got an argument of type '{0}'.".format(
                    arg_type.args[0]))

        # There must be 3 argument descriptors to describe a scalar.
        # TODO in #874: Remove support for the old-style 2 descriptors.
        min_scalar_nargs = 2 + self._offset
        if self._nargs != min_scalar_nargs:
            raise ParseError(
                "In the LFRic API each 'meta_arg' entry must have {0} "
                "arguments if its first argument is 'gh_{{r,i}}scalar', but "
                "found {1} in '{2}'.".format(min_scalar_nargs, self._nargs,
                                             arg_type))

        # Check whether an invalid data type for a scalar argument is passed
        # in. Valid data types for scalars are valid data types in LFRic API.
        # TODO in #874: Remove the support for old-style scalar metadata that
        #               assigns the data type from the scalar name (the 1st
        #               argument).
        #               Note: The main check for the valid scalar data types
        #               will be ParseError in the class constructor and this
        #               scalar init method only needs to check for
        #               InternalError.
        if not self._data_type and self._offset == 0:
            self._data_type = arg_type.args[0].name
            # Translate the old-style argument type into the current one
            self._argument_type = "gh_scalar"
        if (self._data_type not in LFRicArgDescriptor.VALID_SCALAR_DATA_TYPES):
            raise InternalError(
                "LFRicArgDescriptor._init_scalar(): expected one of {0} "
                "as the data type but got '{1}'.".format(
                    LFRicArgDescriptor.VALID_SCALAR_DATA_TYPES,
                    self._data_type))

        # Test allowed accesses for scalars (read_only or reduction)
        scalar_accesses = [AccessType.READ] + \
            AccessType.get_valid_reduction_modes()
        # Convert generic access types to GH_* names for error messages
        api_config = Config.get().api_conf(API)
        rev_access_mapping = api_config.get_reverse_access_mapping()
        if self._access_type not in scalar_accesses:
            api_specific_name = rev_access_mapping[self._access_type]
            valid_reductions = AccessType.get_valid_reduction_names()
            raise ParseError(
                "In the LFRic API scalar arguments must have read-only "
                "('gh_read') or a reduction {0} access but found '{1}' "
                "in '{2}'.".format(valid_reductions, api_specific_name,
                                   arg_type))
        # Reduction access is currently only valid for real scalar arguments
        if self._data_type != "gh_real" and self._access_type in \
           AccessType.get_valid_reduction_modes():
            raise ParseError(
                "In the LFRic API a reduction access '{0}' is only valid "
                "with a real scalar argument, but a scalar argument with "
                "'{1}' data type was found in '{2}'.".format(
                    self._access_type.api_specific_name(), self._data_type,
                    arg_type))

        # Scalars don't have vector size
        self._vector_size = 0
Exemple #2
0
    def _init_scalar(self, arg_type):
        '''
        Validates metadata descriptors for scalar arguments and
        initialises scalar argument properties accordingly.

        :param arg_type: LFRic API scalar argument type.
        :type arg_type: :py:class:`psyclone.expression.FunctionVar`

        :raises InternalError: if argument type other than a scalar is \
                               passed in.
        :raises ParseError: if there are not exactly 3 metadata arguments.
        :raises InternalError: if a scalar argument has an invalid data type.
        :raises ParseError: if scalar arguments do not have a read-only or
                            a reduction access.
        :raises ParseError: if a scalar argument that is not a real \
                            scalar has a reduction access.

        '''
        const = LFRicConstants()
        # Check whether something other than a scalar is passed in
        if self._argument_type not in const.VALID_SCALAR_NAMES:
            raise InternalError(
                "Expected a scalar argument but got an argument of type "
                "'{0}'.".format(arg_type.args[0]))

        # There must be 3 argument descriptors to describe a scalar.
        nargs_scalar = 3
        if self._nargs != nargs_scalar:
            raise ParseError(
                "In the LFRic API each 'meta_arg' entry must have {0} "
                "arguments if its first argument is 'gh_scalar', but "
                "found {1} in '{2}'.".format(nargs_scalar, self._nargs,
                                             arg_type))

        # Check whether an invalid data type for a scalar argument is passed
        # in. Valid data types for scalars are valid data types in LFRic API.
        if self._data_type not in const.VALID_SCALAR_DATA_TYPES:
            raise InternalError(
                "Expected one of {0} as the scalar data type but got '{1}'.".
                format(const.VALID_SCALAR_DATA_TYPES, self._data_type))

        # Test allowed accesses for scalars (read_only or reduction)
        scalar_accesses = [AccessType.READ] + \
            AccessType.get_valid_reduction_modes()
        # Convert generic access types to GH_* names for error messages
        api_config = Config.get().api_conf(API)
        rev_access_mapping = api_config.get_reverse_access_mapping()
        if self._access_type not in scalar_accesses:
            api_specific_name = rev_access_mapping[self._access_type]
            valid_reductions = AccessType.get_valid_reduction_names()
            raise ParseError(
                "In the LFRic API scalar arguments must have read-only "
                "('gh_read') or a reduction {0} access but found '{1}' "
                "in '{2}'.".format(valid_reductions, api_specific_name,
                                   arg_type))
        # Reduction access is currently only valid for real scalar arguments
        if self._data_type != "gh_real" and self._access_type in \
           AccessType.get_valid_reduction_modes():
            raise ParseError(
                "In the LFRic API a reduction access '{0}' is only valid "
                "with a real scalar argument, but a scalar argument with "
                "'{1}' data type was found in '{2}'.".format(
                    self._access_type.api_specific_name(), self._data_type,
                    arg_type))

        # Scalars don't have vector size
        self._vector_size = 0