Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Require variable dimensions in argument list? #197

Closed
gold2718 opened this issue Jun 12, 2019 · 8 comments
Closed

Require variable dimensions in argument list? #197

gold2718 opened this issue Jun 12, 2019 · 8 comments

Comments

@gold2718
Copy link
Collaborator

In the new metadata convention, array variables must document their dimensions. For example:

[o3vmr]
  standard_name = o3_vmr_col
  long_name = O3 volume mixing ratio column
  units = mole/mole
  dimensions = (vertical_layer_dimension)
  type = real | kind = kind_phys
  intent = in

Should the framework require that dimension variables (vertical_layer_dimension in this case) be included in the same metadata table (i.e., also be an argument to the scheme)?

@climbfuji
Copy link
Collaborator

I think yes, most schemes would have this anyway because of performance considerations:

subroutine myfastphysicsscheme(levs,o3vmr)
...
integer, intent(in) :: levs
real(kind=...), intent(in) :: o3vmr(1:levs)

Thus it seems reasonable to me to make this a requirement.

@cacraigucar
Copy link
Collaborator

Just to give a different point of view, Fortran has not required that users pass dimensions for their arrays for quite awhile now. With the introduction of allocatable arrays (again a long time ago), users have been allocating arrays to exact sizes and not needed to bother with the exact dimensionality of their arrays. They've been using ":" in both declarations and within the code itself.

While I agree that the metadata needs to specify the dimension names within the dimensions field, it seems like a burden (and a step backwards) to require that the dimensions be required to be passed as arguments. I imagined that the CPF could keep a master list of dimension names and retrieve the values from it.

I am seeing with chemistry, that there are a number of arrays which are passed through the CPF which have unique (sometimes hardwired) dimensions. In all of these cases, the operations are over the entire dimensions, so the exact sizes are irrelevant and are not values which are being passed.

I am unaware of the performance consideration that Dom says exists. Is this just that the array has been declared larger than it needed to be, or is there some other performance enhancement which occurs with explicitly declared arrays?

Unless there is a strong reason for requiring dimensions to be passed, I am not in favor of making this a requirement.

@gold2718
Copy link
Collaborator Author

@climbfuji
I talked to some of our performance folks and they said they have not been able to detect any performance difference between:

integer, intent(in) :: levs
real(kind=...), intent(in) :: o3vmr(1:levs)

and

integer, intent(in) :: levs
real(kind=...), intent(in) :: o3vmr(:)

On the other hand, the first form bypasses array size checks. This can be troublesome, especially for multi-dimensional arrays and for debugging.

Do you have a (simple) test that shows a performance difference?

@gold2718
Copy link
Collaborator Author

@cacraigucar,

I have some questions about your post:

I imagined that the CPF could keep a master list of dimension names and retrieve the values from it.

The Framework does not have any master list. It collects dimension information from standard names in dimensions metadata attributes but expects someone (e.g., the host model) to have that variable as metadata (that refers to a variable which will store the size at run time). Is that different from what you were thinking?

In all of these cases, the operations are over the entire dimensions, so the exact sizes are irrelevant and are not values which are being passed

How are the operations over "the entire dimensions" being performed? Using array syntax? In a loop? If the answer is a loop, where is the loop size coming from?

@cacraigucar
Copy link
Collaborator

@gold2718

The Framework does not have any master list. It collects dimension information from standard names in dimensions metadata attributes but expects someone (e.g., the host model) to have that variable as metadata (that refers to a variable which will store the size at run time). Is that different from what you were thinking?

As long as "someone" does not need to be the host model, but can be a lower level scheme, that is fine. I guess that's what I meant by a "master list". As long as one scheme's metadata defines the dimension, then other schemes can use it, then I'm happy.

How are the operations over "the entire dimensions" being performed? Using array syntax? In a loop? If the answer is a loop, where is the loop size coming from?

Right now, they are being "use"d from the routines where they are declared. Obviously that will need to change. If I needed the size I would have determined the size using the Fortran intrinsic.

@climbfuji
Copy link
Collaborator

@climbfuji
I talked to some of our performance folks and they said they have not been able to detect any performance difference between:

integer, intent(in) :: levs
real(kind=...), intent(in) :: o3vmr(1:levs)

and

integer, intent(in) :: levs
real(kind=...), intent(in) :: o3vmr(:)

On the other hand, the first form bypasses array size checks. This can be troublesome, especially for multi-dimensional arrays and for debugging.

Do you have a (simple) test that shows a performance difference?

Short answer: no, I don't. I was thinking that the first version would be more performant, but this is probably only true if the compiler knows what levs is (e.g. because it is set as a parameter at compile time), so that's probably not very useful.

@climbfuji
Copy link
Collaborator

Here is an update: ccpp_prebuild.py is now handling this differently. If a dimension that is part of the metadata (or a variable that is required for handling blocked data structures or for determining the "active" status of a variable) is not requested by the scheme itself, the framework adds it to the cap but doesn't pass it to the scheme. I believe this makes most sense.

@gold2718
Copy link
Collaborator Author

gold2718 commented Oct 6, 2020

We do not require dimension variables to be part of a CCPP scheme argument list.

@gold2718 gold2718 closed this as completed Oct 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants