NCAR/ccpp-framework

Add optional attribute to Capgen/Prebuild

Closed this issue · 2 comments

Description

Currently the "optional" attribute is not supported by Capgen or Prebuild.
Conditionally allocated fields needed by a scheme need to be accompanied with the allocation logic provided by the host. This is less than ideal for interoperability, since this requires host model information to access the conditionally allocated field within the scheme.

@DomHeinzeller @gold2718 @peverwhee @nusbaume

Solution

Introduce the optional attribute to Capgen (and Prebuild)

For the Schemes:

  • Any potentially inactive variable must have the optional attribute. Capgen will throw an error during the metadata analysis if it detects a conditionally allocated variable on the host model side, but the scheme doesn’t have the optional attribute in the metadata
  • That means that if only one host model allocates a variable based on a condition, it will force the physics scheme to treat it as an optional variable; this however is a one-way requirement. If a variable is declared as optional in the scheme metadata, it doesn’t have to be conditionally allocated in the host model (it will just always be allocated and present)
  • Capgen will ensure that if a variable has a metadata attribute optional=.true. (default is .false.), it must be declared as an optional variable in the Fortran code
  • We continue to declare arrays in the physics schemes as assumed-size arrays foo(:,:,:)
    In the physics schemes, we test for the presence of optional variables, not for the equivalent of the active attribute in the host model - this removes the dependency of the physics on the host model allocation (why should a scheme have to know)
  • For this to work without having to resort to tests for allocation or association (which would require having to know whether it is an allocatable or pointer - we want to stay away from that), the array must be passed through all layers (i.e. in the auto-generated caps) as an optional variable.
  • Special case: tracer arrays that are passed in its entirety, not each species individually. For these, the current CCPP rules state that the schemes cannot access individual tracers in the tracer array, just loop over/treat the entire array. so there is no problem. However, some of the schemes in CCPP physics currently may violate this rule and may have to be fixed.

For the Caps:

  • Auto-generated caps will need to make sure that when a conditionally allocated variable is passed as an argument (anywhere from the host model interface to the group level), it must be declared as optional (and as assumed shape array, but this should be the case for all arrays anyway). This allows us to test for the presence of the variable all the way down in the physics schemes.
  • Accessing a conditionally allocated array (for allocation/debug checks, array transformations etc) must be wrapped in an “if” statement using the host model active attribute as condition (i.e. not by testing for presence). This is to ensure that the host model metadata matches with the Fortran code.
  • For each variable that is conditionally allocated, there must be a additional logic that (a) declares a local pointer variable of the same type and rank and (b) associates the pointer with the actual variable if the allocation condition is evaluated as .true.; otherwise, pass the unassociated pointer as is. This is necessary for passing chunks of contiguous arrays to a physics scheme in the run phase.

capgen addressed in #529. prebuild still needs to be done

Follow-up work required for capgen is described in #566. The ccpp_prebuild.py implementation is complete when we merge #552.