Skip to content
This repository has been archived by the owner on Apr 18, 2018. It is now read-only.

ENH: Add parallel NF90 single-file output #16

Closed
wants to merge 6 commits into from

Conversation

jklymak
Copy link

@jklymak jklymak commented Jan 13, 2018

Preface

Ported over from the experimental altMITgcm/MITgcm66h#15

Description

This is an implementation of the netcdf4 parallel writing, so that each tile in an mpi process writes to the same file, as described: https://www.unidata.ucar.edu/software/netcdf/netcdf-4/newdocs/netcdf-f90/

Currently it only supports writes using pkg/diagnostics. Set diag_nf90io=.TRUE. in data.diagnostics.

Modifies genmake2 to test for NF90. Also changes .f.o: Makefile directive to have INCLUDES as a flag for the compiler to accommodate use netcdf commands in the *.f files.

See verification/testNF90io/ for a basic example.

See the README.rst in pkg/nf90io for a possible manual entry.

Todo:

  • Add proper test-report compliant vertification
  • Add a test to genmake2 that tests if hdf5 and netcdf have been compiled with parallel support: This may be beyond my expertise. I note that autoconf has such a test, and maybe their macro could be used.
  • Write an appropriate test for automated testing: ditto the above. I've tested this, but I'm not quite sure how one does parallel tests on Travis CI etc: See verification/testNF90io
  • Add to the documentation. (Not sure I should do this now given the state of the new docs)
  • Come up with a way to extend to other packages. How does mnc do the time alignment between the different packages.
  • Redo the test case to use diagnostics
  • Remove some debugging print statements.
  • Remove or add flag to toggle the statevar dump. Probably just add a flag and have it default to .FALSE.

Copy link
Contributor

@jahn jahn left a comment

Choose a reason for hiding this comment

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

It seems a few things got lost in the port from MITgcm66h. Please add changes to diagnostics_out.F that call the nf90io bits, and see other comments in the code.

Is the .oldcode directory there on purpose?

With the requested changes I was able to compile and run the test on our cluster!

#else
CLOSE(ku,STATUS='DELETE')
#endif /* SINGLE_DISK_IO */
CLOSE (ku, STATUS = 'DELETE')
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like a regression. Please restore the SINGLE_DISK_IO changes

#include "SIZE.h"
#include "EEPARAMS.h"
#include "EESUPPORT.h"

Copy link
Contributor

Choose a reason for hiding this comment

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

I had to #include "NF90IO.h" here and in NF90IO_OPEN for this to compile. I think generally we declare functions and their type explicitly in every subroutine that uses them (i.e., a FUNCTION and a type statement), so there may not be a need for this header. But maybe we should discuss this convention @jm-c, @christophernhill?

Copy link
Author

Choose a reason for hiding this comment

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

Oh, hmmm. Maybe you use a more strict compile options than me?

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, I am using stock linux_amd64_gfortran...

& SQUEEZE_RIGHT , 1)

C Close the open data file
CLOSE(iUnit)
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be updated for SINGLE_DISK_IO (see diagnostics_readparms.F)

tools/genmake2 Outdated
@@ -1,5 +1,7 @@
#! /usr/bin/env bash
#
# $Header$
# $Name$
Copy link
Contributor

Choose a reason for hiding this comment

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

Regression: CVS keywords have been removed.

tools/genmake2 Outdated
echo "Somehow h5pcc not compiled w/ parallel" >> $LOGFILE
return
fi
echo " ...returns yes" >> $LOGFILE
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we really need these new tests? I would just test compilation of f90tst_parallel.f90 and maybe on failure print some hints to help the user figure out whether she has parallel netcdf support. netcdf 4.5, for instance, has nc-config --has-parallel. I don't like the use of $NETCDF and $HDF5 too much as most optfiles do not define or use these right now.

Copy link
Author

Choose a reason for hiding this comment

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

Ah, I remember now. The issue is that these tests don't fail if parallel support is not enabled. And if I remember correctly the error was a bit mysterious to the end user.

OTOH, I agree that there doesn't seem to be an easily robust way to check for parallel netcdf. You can always call nc-config but it is hard to tell if it is the right nc-config on a supercomputer with many possible modules. Thats why I was suggesting the environment variables. Some supercomputers seem to set these environment variables, and if they don't I don't think its a heavy ask to ask the user to set them, rather than just providing bare $LIB and $INC lists. But, I don't think sorting all that out should hold this up, just something to consider.

tools/genmake2 Outdated
echo "<<< f90tst_parallel.f90 ===" >> f90tst_parallel.log
echo "$FC $FFLAGS $FOPTIM -c f90tst_parallel.f90 \ " >> f90tst_parallel.log
echo " && $LINK $FFLAGS $FOPTIM -o f90tst_parallel.o $LIBS" >> f90tst_parallel.log
$FC $FFLAGS $FOPTIM $INCLUDES -c ${TOOLSDIR}/maketests/f90tst_parallel.f90 >> f90tst_parallel.log 2>&1 \
Copy link
Contributor

Choose a reason for hiding this comment

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

Please change to F90C here and below. Many optfiles assume that FC only sees fixed-form files and will not compile this.

Copy link
Author

Choose a reason for hiding this comment

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

OK, my mind is hazy on this, though we had a discussion in altMITgcm/MITgcm66h#15

I don't actually ever compile the rest of the code with F90C, including the new stuff. I think I just assume that FC will compile F90 code. I tried specifically using F90C for the new files, but the compile options don't carry over, and I wasn't sure how to proceed (I don't have access or experience with compiler options really).

So... I can do this, but I'm just flagging that there is still some inconsistency, and maybe someone else needs to a) Force Push onto this PR (which anyone w/ commit bit is welcome to do), or b) merge and fix later.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think we effectively use FC for fixed-form source files (with file extension .F) and F90C for free-form ones (with extension .F90). There can be Fortran-90 features in .F files and these may then just not work with some compilers (like g77). @jm-c correct me if I'm wrong.

@jklymak
Copy link
Author

jklymak commented Jan 14, 2018

Thanks @jahn thats very helpful. Not fixing genmake2 yet, just because that may take me a bit of concentrated time to sort through again, not because I disagree w/ your suggestions. Marking WIP just so it doesn't get merged yet.

@jklymak jklymak changed the title ENH: Add parallel NF90 single-file output WIP: ENH: Add parallel NF90 single-file output Jan 14, 2018
@jahn
Copy link
Contributor

jahn commented Jan 14, 2018

Thanks! It compiles and runs now.

There are still things to think about, such as the tests for parallel netcdf (as you pointed out) and naming of dimensions, etc., so still WIP!

@jklymak jklymak changed the title WIP: ENH: Add parallel NF90 single-file output ENH: Add parallel NF90 single-file output Jan 14, 2018
@jklymak
Copy link
Author

jklymak commented Jan 14, 2018

Thanks @jahn

Removing the WIP, because I think this could be merged w/o hurting anything else.

Of the two remaining issues

genmake2 checks

For now I think this just needs to be a documentation issue. It'll probably evolve as more people use the package and let us know what issues they have on various machines.

Naming conventions

Totally open to working on naming of dimensions with folks. I do think this is somewhat urgent, because we don't want people to start writing downstream code and then yanking the rug out from under them in three or four months.

OTOH, I will agitate to merge this sooner rather than later so I don't have to keep rebasing/merging. When the documentation is merged we can stipulate that the naming convention of the dimensions is subject to change for a release cycle or two. And further PRs to get that all straight could be made after this is in place.

@jahn
Copy link
Contributor

jahn commented Jan 14, 2018

Note that this is still not the final git repository but frozen at CVS from October. So we'll have to rebase it a least once more...

@jklymak
Copy link
Author

jklymak commented Jan 14, 2018

How is that going? Moving the canonical repository could theoretically happen before the docs are finished (so long as there are enough docs that folks can download the code, but that is surely straight-forward). Happy to help where I can...

@edoddridge
Copy link
Contributor

It's great to have a test included, but I couldn't run it with testreport. Perhaps I missed something, but I got the following error message:

can't read "testNF90io/results/output.txt" -- skipping testNF90io

The readme looks like a great base for the documentation for this package.

@jklymak
Copy link
Author

jklymak commented Jan 15, 2018

OK, it seems the verification experiments all want an output.txt. I've not supplied one. Maybe that is the wrong place for testNF90io? I'm not really up on what the verification expts are supposed to check or how testreport is meant to behave so any guidance is welcome.

It does seem that just running the job and looking at output.txt will be a weak indication that things are working. The only strong indication that things are working is using a multi-core machine with parallel netcdf installed.

@jahn
Copy link
Contributor

jahn commented Jan 15, 2018 via email

@jklymak
Copy link
Author

jklymak commented Jan 15, 2018

I wrote that script (checkit.py) around xarray but it could easily be written around ncdump or maybe nccmp? It'd require the netcdf binaries in the repository, but they need not be too large.

@edoddridge
Copy link
Contributor

I'm a big fan of testing, but not a fan of including binaries in the repo. xarray is an easily satisfied dependency that doesn't require binaries in the repo - I'd vote we stick with that.

I'll let someone else (@jm-c or @christophernhill perhaps?) jump in about the philosophy behind testreport, but you seem to be advocating for something like a unit test for NF90io. In which case, I'm all for it, but we should probably have a discussion about where it goes - a new unit_test folder? (Let's pause that discussion until the real repo is online though)

Copy link
Contributor

@edoddridge edoddridge left a comment

Choose a reason for hiding this comment

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

doc/tag-index needs to be updated. (The docs don't currently mention this, but it's in the pipeline)

Copy link
Contributor

@jahn jahn left a comment

Choose a reason for hiding this comment

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

Please fix endianness and axes order of the binary input files.

x = x-x[int(nx/2)]

with open(outdir+"/delXvar.bin", "wb") as f:
dx.tofile(f)
Copy link
Contributor

Choose a reason for hiding this comment

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

This writes native-endian. Can you change to big-endian here and below, e.g.,

    dx.astype('>f8').tofile(f)

Copy link
Author

Choose a reason for hiding this comment

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

Yeah, I'll do it, but reluctantly... At some point it'd be nice to phase out big-endian, unless VAX makes a comeback someday 😉

f.close()

# save T0 over whole domain
TT0 = matlib.repmat(T0,nx,ny).T
Copy link
Contributor

Choose a reason for hiding this comment

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

This does not give the correct order of axes. Can you fix?

Copy link
Author

Choose a reason for hiding this comment

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

I'll get rid of matlib all-together because its disappearing from Matplotlib...

@jahn
Copy link
Contributor

jahn commented Jan 16, 2018

If we keep this test here in verification, we should add the binary input files, reference output and build and run directories with .gitignore files (copied from other experiments). Also SIZE.h needs to be renamed to SIZE.h_mpi and maybe a single-processor SIZE.h added. monitorFreq should be reduced to give more than one monitor output. I would prefer a name that doesn't start with "test", maybe "bump_with_nf90io". Ideas?

I think this test is useful, even without a way to automatically check the resulting netCDF file (which would also be useful, of course).

@jahn
Copy link
Contributor

jahn commented Jan 16, 2018

Looks like this works only with nSx=1 and nSy=1. If this is not easy to fix, there should at least be a STOP in the case that doesn't work.

@jklymak
Copy link
Author

jklymak commented Jan 16, 2018

wrt nSx, ummm... hmmm. I've not tested for that, but I do iterate over bi and bj. Do you think its incorrect?

@jahn
Copy link
Contributor

jahn commented Jan 16, 2018 via email

err = nf90_put_var(ncid, varid,
& dat(1:sNx, 1:sNy, 1:Nr, bi, bj),
& start = start, count = count)
CALL nf90ERR(err, "Putting data into file", myThid)
Copy link
Author

Choose a reason for hiding this comment

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

@jahn I think that the tiling error would be in here (and similar). I don't see anything obvious, but maybe I did something dumb....

Copy link
Contributor

Choose a reason for hiding this comment

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

My guess would be that in collective mode each processor has to make exactly one call to nf90_put_var for each record. If that's true, one would have to combine the tiles one processor controls into one array that can be passed to nf90_put_var. I couldn't verify this in the netCDF docs, though. Maybe you know where to look?

Copy link
Author

Choose a reason for hiding this comment

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

Oh, I have no idea - not claiming to be a netcdf expert, just seemed easy to put this together so I did.

I think we could proceed for now by putting a STOP in somewhere.

If what you say above is correct, I'd need guidance on how frequently muti-threading is used by folks as to whether it was worth the extra code to gather each processor's output and save it. Certainly thats substantially more complicated and memory intensive than what is done now. If its worth it (i.e. many of people actually multithread) then we should do it as a future refinement. Myself, I'm not even sure how to run a multithreaded job, though no doubt I could figure it out; maybe as easy as just setting nSx/nSy?

Copy link
Contributor

Choose a reason for hiding this comment

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

This is not just for multi-threading, one can run with multiple tiles per processor in a single thread (that's what these loops are for). Sometimes it is convenient if one can run on fewer processors without having to change the tiling. And testreport uses this to run parallel tests on as many processors as there are available.

Copy link
Author

Choose a reason for hiding this comment

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

Confirmed on my machine. Advice appreciated. We could gather a processer-global temp variable and nf90_put_var that variable instead. I think that seems reasonable, and not too much work.

Copy link
Author

Choose a reason for hiding this comment

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

I think I found my bug and/or implimented gathering. Not sure gathering is necessary. Basically, I needed to trim the arrays qdiag to Nr because they are NrMax in the k-direction, and that caused bad data to be in the routines if sNx>1...

Copy link
Author

Choose a reason for hiding this comment

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

Yeah, didn't need to gather, just needed to pass the properly trimmed data to the writing functions. @jahn, this should work now.

Working on making the example testreport ready.

Copy link
Contributor

Choose a reason for hiding this comment

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

yes it does!

@jklymak
Copy link
Author

jklymak commented Jan 17, 2018

How does the SIZE.h_mpi get tested? Normal genmake doesn't move it into SIZE.h automagically. Does testreport do it?

@jahn
Copy link
Contributor

jahn commented Jan 17, 2018

Yes, testreport -mpi (or -MPI <N>) uses SIZE.h_mpi. The latter also modifies it to match the actual number of processors, changing nSx or nSy.

@jm-c
Copy link
Contributor

jm-c commented Jan 17, 2018 via email

@jklymak
Copy link
Author

jklymak commented Jan 18, 2018

  • moved verification to verification/nf90io_gaussian_bump
  • added (big-endian!!) data files.

For the rest to get testreport working I suspect will require someone who understands it better than me. I think its pretty close, but I don't see how to test the MPI, -ieee was not working for me, etc etc. No doubt the fault of my build_option file.


# save T0 over whole domain
slope = np.arange(nx) * 0.2
TT0 = T0[None, None, :] + 0 * y[None, :, None] + slope[:, None, None]
Copy link
Contributor

Choose a reason for hiding this comment

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

sorry for being a pain, but the axes order is still backwards.

Copy link
Author

Choose a reason for hiding this comment

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

🐑

@jahn
Copy link
Contributor

jahn commented Jan 18, 2018

For the testreport run to be meaningful, you have to reduce monitorFreq so that more than 1 time step is written. I've set monitorFreq=62, in data. You'll have to update the reference output.

SIZE.h has to be set up for a one-processor run, i.e., nPx=1 and nPy=1. It is only used for non-mpi runs.

To test with mpi, with a specific number of processors, use something like this:

./testreport -MPI 4 -t nf90io_gaussian_bump

This should work if your optfile supports mpi.

If you cannot get -ieee to work, you can pass -fast to testreport and it will compile with non-ieee options. Testing with -ieee is better, though, because more warnings are turned on (in most optfiles).

@jklymak
Copy link
Author

jklymak commented Jan 18, 2018

Thanks, still a bit confused: output.txt is for the non-mpi run. I assume somehow the comparison in testreport doesn't care about my particular setup.

What do I use for output.txt for the yes-mpi run?

I assume when I run testreport it makes an output.txt to compare with the one in results? I can't find it. Does it get cleaned up somehow? It'd be nice to use it as the one in results...

@jahn
Copy link
Contributor

jahn commented Jan 18, 2018

results/output.txt is used for both mpi and non-mpi runs. For the mpi run, testreport compares run/STDOUT.0000 to results/output.txt, so this is the file to copy in a case where the mpi run is more interesting than the non-mpi one.

@jklymak
Copy link
Author

jklymak commented Feb 26, 2018

Closing in favour of the proper repository. MITgcm/MITgcm#31

@jklymak jklymak closed this Feb 26, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants