scream
scream copied to clipboard
Should the default Field initialization value be a FillValue?
The question is in regards to when a field has been declared and the memory is allocated, but before any values have been assigned to it. I think that the default is to assign 0.0 as a placeholder. Should this instead be the FillValue?
If the default is zero this can give the false impression that some fields are in fact zero when they may have just not been touched yet. Which would be a difficult bug to catch. But if they are masked values they will pop up in output as something worth investigating.
I am actually surprised to see that 0.0 is indeed our default value for fields. I actually thought we used NaN (or whatever is the "invalid" vallue according to ekat::ScalarTraits
).
Imho, we should not mix the concept of "FillValue" (a netcdf thing) with the default initialization value of a field. I would very much like to have random values or NaN, since they are better to spot usage of uninitialized values.
I would be happy with NaN as well. Anything except a reasonable value like 0.0. Note, I couldn't find where fields are initialized so I'm not 100% confident it is 0.0, but I'm basing this on the surface coupling standalone test which checks that some exported fields (which haven't been set yet) are equal to 0.0 after initialization. This leads me to believe that fields start off as 0.0.
We do not explicitly set an initialization value. We just create the managed view, and Kokkos handles the allocation. You should not rely on 0.0 be the value in the view. Right now, that seems to be the case, as I infer from the fact that an optional constructor arg for Kokkos::View is Kokkos::WithoutInitializing
, which suggests that Kokkos does init to 0 by default. However, speaking to some Kokkos folk, I had the impression that this may or may not be the case in the future.
ahhh okay, that makes sense. It should be trivial to just copy NaN to a field at initialization and thus have an init value we can trust. right?
I would recommend against using the special value of NaN for anything intentionally.
That's a fair point. Does anyone have a good idea of what a valid initial condition value should be? What does EAM do?
I would recommend against using the special value of NaN for anything intentionally.
I disagree. NaN can trigger FPEs, so it can be used to detect when we are reading values that were not yet correctly initialized. One may argue "doesn't our memcheck build detect that?", but the answer is "not for Kokkos::View", where Kokkos (unless told not to) should init everything to 0. So using a value that will trigger errors is a good way to protect against unintentional use of the value. With a NaN, our FPE build will most certainly catch if we use uninitialized values. If the array is used correctly, the NaN values will be overwritten before being used inside any operation, so they should not cause any problem.
I suspect Noel is thinking of the woes caused by ELM initializing everything to NaN, then getting exceptions in debug mode where padded arrays perform operations using NaNs for cells that are never actually used for real calculations. Could we init things to NaN without having cells included just for padding cause problems?
Even if we don't explicitly init stuff to NaN, some values in the padded entries will inevitably cause FPEs (e.g., divide by 0, or sqrt of neg number), regardless of how one inits them. That's why, in EAMxx, we disable FPEs when our pack size is larger than 1, precisely for this reason. And our FPE build has a pack size of 1, so that it can catch FPEs that are in the "physical" part of the array, and not the padding.
Ok great. Thanks Luca. Does this address your concern, @ndkeen ?