-
Notifications
You must be signed in to change notification settings - Fork 135
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
Mixed precision random_numbers_mod #1191
Conversation
Initial implementation of mixed precision random_numbers_mod.
Rather than requiring that sample moments be within 5% of their expected values, calculate the standard deviations of sample moments and require that each sample moment be within one standard deviation of its expected value.
Re-order the subroutines to make the CI pass.
Re-order the unit test subroutines (again) in an effort to make the github CI pass.
Rather than re-ordering the subroutines, use an abstract interface to specify the dummy argument by which either test_sample_1d or test_sample_2d is passed.
type(randomNumberStream), intent(inout) :: stream | ||
real, intent( out) :: number | ||
real(RN_KIND_), intent( out) :: number |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could RN_KIND_ be changed to FMS_RN_KIND_? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed in fc57559
@@ -92,6 +92,8 @@ | |||
!> @{ | |||
module MersenneTwister_mod | |||
! ------------------------------------------------------------- | |||
use platform_mod, only: r8_kind | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
line 106, could -2147483648_8 be changed to UMASK = -2147483648_i8_kind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could... but the value gets assigned to a 4-byte integer, so I'm pretty confused what the original author had in mind here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've removed the _8
in fc57559... but I'm feeling a bit uneasy about it, since someone presumably put it there for a reason that's not clear to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that the _8
was a workaround to make it compile with GNU.
I've replaced this constant, as well as several others, with hexadecimal representations in 1d3f321.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trying to make the hexadecimal constants work with older versions of gfortran brought me down a rabbit hole that I don't wish to explore any further. So I'm just going to revert those constants back to decimal values, leave an _i8_kind
where the _8
was, and stop asking questions... some stones are better left unturned......
test_fms/random_numbers/Makefile.am
Outdated
test_random_numbers_r4_SOURCES = test_random_numbers.F90 | ||
test_random_numbers_r8_SOURCES = test_random_numbers.F90 | ||
|
||
test_random_numbers_r4_CPPFLAGS = $(AM_CPPFLAGS) -DKIND_=r4_kind |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-DTEST_RN_KIND_ (just for consistency with the other unit tests)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed in fc57559
|
||
do i=1, n_moments | ||
moment_mu(i) = CALC_MOMENT_(i) | ||
moment_sigma(i) = sqrt((CALC_MOMENT_(2*i) - moment_mu(i)**2) / n) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
real(n,k)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed in fc57559
integer, parameter :: n0_1d = 2500 !> Initial length of 1D random sample vector | ||
integer, parameter :: n0_2d = 50 !> Initial dimensions of 2D random sample array | ||
|
||
integer, parameter :: seeds(0:*) = [0, -5, 3] !> Seed constants |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're a Fortran guru, this is the first time I'm seeing something like this lol. Does this notation work with all compilers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tested it with Intel, GNU, and Cray and it works with all of them. It seems that assumed-size arrays are actually older than the dinosaurs (they're a Fortran 77 feature), while square bracket array constructors are an F2003 feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you confirm that this works with the nvdia compilers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, it doesn't work in nvfortran 23.3. It gets the lower index wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to a 1-indexed array in b978a99.
call fms_init | ||
|
||
if (mpp_npes() .ne. 4) then | ||
call mpp_error(fatal, "The random_numbers unit test requires four PEs") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be FATAL or should it be a NOTE/WARNING and then exit the program? Or maybe check at the script level and if 4 pes are not available, skip the test...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the problem with using FATAL
? I believe it should end up with four PEs any time it's run through the script, so this is really just a sanity check that shouldn't fail under normal circumstances.
end subroutine test_getRandomNumbers | ||
|
||
! Expression for the expectation value of the i-th raw moment | ||
#define CALC_MOMENT_(i) (1._k / real(i + 1, k)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where did this equation come from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The m-th raw moment of a distribution, by definition, is the integral of x^m times f(x), where f(x) is the distribution's probability density function. For the uniform distribution, f(x)=1 for 0<x<1, and f(x)=0 outside of that range. So the m-th moment is the integral from 0 to 1 of x^m, which is 1/(m + 1).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's been a while since I thought about this stuff. Why is it a uniform distribution?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comments in random_number_mod
don't seem to explicitly state that the distribution is uniform. But, I think the term "random number generator" usually tends to mean "uniform random number generator", unless some other distribution is explicitly stated. The [0, 1] output range is also a hint that it's intended to output uniform random numbers.
end function test_sample_2d | ||
|
||
!> Check that the first 1,000 moments of a sample are within one standard | ||
!> deviation of their expected values |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why one standard deviation? do we know what the distribution function looks like?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One standard deviation was an empirical choice, based on the observation that the test passes within a couple seconds. But if we need the test to run faster, we could use a more lenient condition like 1.5 or 2 standard deviations.
I believe the central limit theorem implies that the distribution of sample moments should be approximately Gaussian, at least in the limit as the sample size approaches infinity.
Several constants in mersennetwister.F90 have been replaced with hexadecimal representations.
integer, parameter :: n0_1d = 2500 !> Initial length of 1D random sample vector | ||
integer, parameter :: n0_2d = 50 !> Initial dimensions of 2D random sample array | ||
|
||
integer, parameter :: seeds(0:*) = [0, -5, 3] !> Seed constants |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you confirm that this works with the nvdia compilers?
Avoid using a 0-indexed array to work around an nvfortran bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks fine to me.
BREAKING CHANGE: In coupler_types.F90, `coupler_nd_field_type` and `coupler_nd_values_type` have been renamed to indicate real kind value: `coupler_nd_real4/8_field_type` and `coupler_nd_real4/8_values_type`. The `bc` field within `coupler_nd_bc_type` was modified to use r8_kind within the value and field types, and an additional field added `bc_r4` to use r4_kind values. Includes: * feat: eliminate use of real numbers for mixed precision in `block_control` (#1195) * feat: mixed precision field_manager (#1205) * feat: mixed precision random_numbers_mod (#1191) * feat: mixed precision time_manager reals to r8 and clean up (#1196) * feat: mixed Precision tracer_manager (#1212) * Mixed precision monin_obukhov (#1116) * Mixed precision: `monin_obukhov` unit tests (#1272) * mixed-precision diag_integral_mod (#1217) * mixed precision time_interp (#1252) * mixed precision interpolator_mod (#1305) * Mixed precision astronomy (#1092) * Mixed precision `data_override_mod` (#1323) * mixed precision exchange (#1341) * coupler mixed precision (#1353) * Mixed precision topography_mod (#1250) --------- Co-authored-by: rem1776 <Ryan.Mulhall@noaa.gov> Co-authored-by: MiKyung Lee <58964324+mlee03@users.noreply.github.com> Co-authored-by: mlee03 <Mikyung.Lee@lscamd50-d.gfdl.noaa.gov> Co-authored-by: Caitlyn McAllister <65364559+mcallic2@users.noreply.github.com> Co-authored-by: Jesse Lentz <42011922+J-Lentz@users.noreply.github.com>
Initial implementation of mixed precision random_numbers_mod and unit tests.
Checklist:
make distcheck
passes