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

Enable single-precision floating point unit tests for CI #1698

Merged
merged 7 commits into from
Jul 22, 2021

Conversation

oskooi
Copy link
Collaborator

@oskooi oskooi commented Jul 22, 2021

Enables single-precision floating point unit tests as part of the CI only for Python 3.9 with MPI. I have tested that all tests (C++ and Python) are passing for the entire CI matrix: [serial, MPI] x [Python 3.6, Python 3.9]. The changes in this PR involve mostly reducing the relative tolerance when checking against hard-coded values for a handful of the unit tests. In some of these modified tests involving a comparison of two NumPy arrays, the comparator function numpy.testing.assert_allclose was replaced with assertVectorsClose due to #1575. (We should probably replace all uses of numpy.testing.assert_allclose but that can be done in a separate PR.)

Three of the unit tests are skipped for single precision:

  1. test_multilevel_atom.py: the change in values was larger than just a few decimal digits.
  2. test_eigfreq.py: the CW solver fails to converge.
  3. test_epsilon_warning of test_simulation.py: the dispersive material Molybdenum (Mo) from the materials library is causing the fields to blow up.

@codecov-commenter
Copy link

codecov-commenter commented Jul 22, 2021

Codecov Report

Merging #1698 (ad65694) into master (c8f9e8e) will increase coverage by 0.08%.
The diff coverage is n/a.

@@            Coverage Diff             @@
##           master    #1698      +/-   ##
==========================================
+ Coverage   73.24%   73.32%   +0.08%     
==========================================
  Files          13       13              
  Lines        4518     4525       +7     
==========================================
+ Hits         3309     3318       +9     
+ Misses       1209     1207       -2     
Impacted Files Coverage Δ
python/simulation.py 76.24% <0.00%> (+0.16%) ⬆️

@@ -16,7 +16,7 @@
_FD_STEP = 1e-4

# The tolerance for the adjoint and finite difference gradient comparison
_TOL = 2e-2
_TOL = 0.1 if mp.is_single_precision() else 0.02
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense that the error in finite-difference approximations would depend sensitively on the precision. If you are computing [f(x+δ)-f(x)]/δ, the optimal choice of δ depends sensitively on the precision, and if δ is too small compared to the precision you can see a large "catastrophic cancellation" error.

@@ -53,7 +52,8 @@ def test_3rd_harm_1d(self):

harmonics = [self.k, self.amp, mp.get_fluxes(self.trans1)[0], mp.get_fluxes(self.trans3)[0]]

np.testing.assert_allclose(expected_harmonics, harmonics)
tol = 3e-5 if mp.is_single_precision() else 1e-7
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also makes sense — there is little hope of getting 7 significant digits in single precision.

@stevengj
Copy link
Collaborator

We will also want to change the default tolerance of the CW solver — it currently defaults to 1e-8, but I would change it to be 1e-8 in double precision and 1e-5 in single precision.


class TestMultiLevelAtom(unittest.TestCase):

@unittest.skipIf(mp.is_single_precision(), "double-precision floating point specific test")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to open an issue about this and ping Alex Cerjan. I'm not sure why a Maxwell–Bloch simulation would be super sensitive to floating-point errors.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we are entering some sort of chaotic regime, in which the precise details (phase etcetera) are extremely sensitive to initial conditions and small calculational errors.

@@ -977,7 +977,9 @@ int main(int argc, char **argv) {
#endif

if (!nonlinear_ex(vol1d(1.0, 30.0), one)) meep::abort("error in 1D nonlinear vacuum\n");
if (!nonlinear_ex(vol3d(1.0, 1.2, 0.8, 10.0), one)) meep::abort("error in 3D nonlinear vacuum\n");
if (sizeof(realnum) == sizeof(double)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another chaotic case??

@stevengj stevengj merged commit d662b0c into NanoComp:master Jul 22, 2021
@oskooi oskooi deleted the single_precision_tests branch July 22, 2021 20:00
bencbartlett pushed a commit to bencbartlett/meep that referenced this pull request Sep 9, 2021
* lower tolerance of various tests when compiled with single precision

* add more tests

* fix more tests

* fix for test_get_array_metadata.py

* only compile with single precision for Python 3.9 with MPI

* cleanups and tweaks

* fix harmonics.cpp
mawc2019 pushed a commit to mawc2019/meep that referenced this pull request Nov 3, 2021
* lower tolerance of various tests when compiled with single precision

* add more tests

* fix more tests

* fix for test_get_array_metadata.py

* only compile with single precision for Python 3.9 with MPI

* cleanups and tweaks

* fix harmonics.cpp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants