From 679554c254e25cf9b9110f69e2f874fbb9153bf7 Mon Sep 17 00:00:00 2001 From: Andrew Pontzen Date: Tue, 16 Apr 2024 20:33:03 +0100 Subject: [PATCH 01/17] Preliminary GadgetHDF support This loads into pynbody, but is not yet actually tested for initialising a Gadget4/Arepo/Swift sim --- CMakeLists.txt | 9 ++-- genetIC/Makefile | 22 +++++--- genetIC/src/ic.hpp | 5 ++ genetIC/src/io.hpp | 9 +++- genetIC/src/io/gadget.hpp | 72 ++++++++++++++++----------- genetIC/src/simulation/coordinate.hpp | 12 +++++ tools/compare.py | 29 ++++++++--- 7 files changed, 109 insertions(+), 49 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bca192e9..73353b22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,9 +4,9 @@ project(IC) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/genetIC) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -g ") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -g ") -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -DDEBUG_INFO") +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -DOPENMP -fopenmp -DDEBUG_INFO") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fopenmp -O3 -DOPENMP") set(SOURCE_FILES @@ -20,6 +20,7 @@ set(SOURCE_FILES genetIC/src/io.hpp genetIC/src/io/grafic.hpp genetIC/src/io/gadget.hpp + genetIC/src/io/gadgethdf.hpp genetIC/src/io/input.hpp genetIC/src/io/tipsy.hpp genetIC/src/main.cpp @@ -66,7 +67,7 @@ set(SOURCE_FILES include_directories( /opt/local/include ) link_directories(/opt/local/lib ) include_directories( genetIC/ ) -link_libraries(fftw3 m fftw3f fftw3_threads gsl gslcblas) +link_libraries(fftw3 m fftw3f fftw3_threads gsl gslcblas hdf5 hdf5_cpp) exec_program( @@ -116,4 +117,4 @@ add_definitions(-DCUBIC_INTERPOLATION -DZELDOVICH_GRADIENT_FOURIER_SPACE ) add_compile_options(-Wextra) -add_executable(genetIC ${SOURCE_FILES}) \ No newline at end of file +add_executable(genetIC ${SOURCE_FILES}) diff --git a/genetIC/Makefile b/genetIC/Makefile index 7a0df0ac..359a8133 100644 --- a/genetIC/Makefile +++ b/genetIC/Makefile @@ -1,5 +1,5 @@ # Reasonably sensible defaults -CFLAGS ?= -Wall -g -lpthread -O3 -fopenmp -std=c++14 -fdiagnostics-color=auto -I`pwd` +CFLAGS ?= -Wall -g -lpthread -O3 -fopenmp -std=c++17 -fdiagnostics-color=auto -I`pwd` # Here are code options. Probably don't fiddle with these unless you know what you're doing. # @@ -38,6 +38,10 @@ GSLFLAGS = -lgsl -lgslcblas FFTW = -DFFTW3 -DFFTW_THREADS FFTWLIB = -lfftw3 -lfftw3f -lfftw3_threads +HDFLIB = -lhdf5 -lhdf5_cpp + + + # Provide information on the git repository, to be printed out on each run GIT_MODIFIED = $(shell git ls-files -m 2>/dev/null | tr "\n" " " ) GIT_VERSION = $(shell git rev-parse --short HEAD 2>/dev/null) @@ -65,7 +69,7 @@ ifeq ($(HOST3), pfe) CXX = /nasa/pkgsrc/2016Q2/gcc5/bin/g++ CPATH = /u/apontzen/genetIC/genetIC:/nasa/gsl/1.14/include/:/nasa/intel/Compiler/2016.2.181/compilers_and_libraries_2016.2.181/linux/mkl/include/fftw LPATH = /nasa/gsl/1.14/lib/ -L/nasa/intel/Compiler/2016.2.181/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64/ - CFLAGS = -Wall -g -O3 -fopenmp -std=c++14 -fdiagnostics-color=auto -I`pwd` -DOPENMP -DDOUBLEPRECISION + CFLAGS = -Wall -g -O3 -fopenmp -std=c++17 -fdiagnostics-color=auto -I`pwd` -DOPENMP -DDOUBLEPRECISION FFTWLIB = -ldl -lpthread -lm -lstdc++ -lgfortran -lmkl_intel_ilp64 -lmkl_gnu_thread -lmkl_core FFTW = -DFFTW3 -DFFTW_THREADS GSLFLAGS = /nasa/gsl/1.14/lib/libgsl.a /nasa/gsl/1.14/lib/libgslcblas.a @@ -74,20 +78,26 @@ endif ifeq ($(HOST), Snowd) CPATH = /opt/local/include/ LPATH = /opt/local/lib/ - CFLAGS = -O3 -fopenmp -std=c++14 -fdiagnostics-color=auto -I`pwd` -DOPENMP -DDOUBLEPRECISION + CFLAGS = -O3 -fopenmp -std=c++17 -fdiagnostics-color=auto -I`pwd` -DOPENMP -DDOUBLEPRECISION CXX = /opt/local/bin/clang++-mp-6.0 endif ifeq ($(HOST), clema) CPATH = /opt/local/include/ LPATH = /opt/local/lib/ - CFLAGS = -O2 -g -fopenmp -std=c++14 -fdiagnostics-color=auto -I`pwd` -DOPENMP -DDOUBLEPRECISION + CFLAGS = -O2 -g -fopenmp -std=c++17 -fdiagnostics-color=auto -I`pwd` -DOPENMP -DDOUBLEPRECISION CXX = /opt/local/bin/clang++-mp-6.0 endif +ifeq ($(HOST), butte) + CXX = /opt/homebrew/Cellar/llvm/17.0.6_1/bin/clang++ + CPATH = /opt/homebrew/include/ + LPATH = /opt/homebrew/lib/ +endif + ifeq ($(HOST), jasmi) CXX = /opt/local/bin/g++-mp-11 -L/opt/local/lib/ - CFLAGS = -O3 -g -fopenmp -std=c++14 -I`pwd` -DOPENMP -DDOUBLEPRECISION + CFLAGS = -O3 -g -fopenmp -std=c++17 -I`pwd` -DOPENMP -DDOUBLEPRECISION endif ifeq ($(HOST), Rhodo) @@ -134,7 +144,7 @@ all: genetIC %.o: %.cpp ; $(CXX) $(CFLAGS) $(CODEOPTIONS) $(GIT_VARIABLES) -I$(CPATH) $(FFTW) -c $< -o $@ genetIC: src/main.o src/tools/filesystem.o src/tools/progress/progress.o src/tools/logging.o - $(CXX) $(CFLAGS) -o genetIC $(GIT_VARIABLES) -I$(CPATH) $(FFTW) src/main.o src/tools/filesystem.o src/tools/progress/progress.o src/tools/logging.o -L$(LPATH) $(GSLFLAGS) -lm $(FFTWLIB) + $(CXX) $(CFLAGS) -o genetIC $(GIT_VARIABLES) -I$(CPATH) $(FFTW) $(HDFLIB) src/main.o src/tools/filesystem.o src/tools/progress/progress.o src/tools/logging.o -L$(LPATH) $(GSLFLAGS) -lm $(FFTWLIB) clean: rm -f genetIC diff --git a/genetIC/src/ic.hpp b/genetIC/src/ic.hpp index 9e7ac0f6..d4d6bbaa 100644 --- a/genetIC/src/ic.hpp +++ b/genetIC/src/ic.hpp @@ -1285,6 +1285,11 @@ class ICGenerator { cosmology, static_cast(outputFormat), nGadgetFiles); break; + case OutputFormat::gadgethdf: + gadgethdf::save(getOutputPath(), boxlen, *pMapper, pParticleGenerator, cosmology, + nGadgetFiles); + break; + case OutputFormat::tipsy: tipsy::save(getOutputPath() + ".tipsy", boxlen, pParticleGenerator, pMapper, cosmology); diff --git a/genetIC/src/io.hpp b/genetIC/src/io.hpp index ea23ce46..e0f0460a 100644 --- a/genetIC/src/io.hpp +++ b/genetIC/src/io.hpp @@ -15,6 +15,7 @@ namespace cosmology { #include "io/input.hpp" #include "io/gadget.hpp" +#include "io/gadgethdf.hpp" #include "io/tipsy.hpp" #include "io/grafic.hpp" @@ -31,7 +32,7 @@ namespace cosmology { namespace io { enum class OutputFormat { - unknown = 1, gadget2 = 2, gadget3 = 3, tipsy = 4, grafic = 5 + unknown = 1, gadget2 = 2, gadget3 = 3, tipsy = 4, grafic = 5, gadgethdf = 6 }; std::ostream &operator<<(std::ostream &outputStream, const OutputFormat &format) { @@ -50,6 +51,10 @@ namespace io { break; case OutputFormat::grafic: outputStream << "grafic"; + break; + case OutputFormat::gadgethdf: + outputStream << "gadgethdf"; + break; } return outputStream; } @@ -69,6 +74,8 @@ namespace io { format = OutputFormat::tipsy; } else if (s == "grafic") { format = OutputFormat::grafic; + } else if (s == "gadgethdf") { + format = OutputFormat::gadgethdf; } else { inputStream.setstate(std::ios::failbit); } diff --git a/genetIC/src/io/gadget.hpp b/genetIC/src/io/gadget.hpp index 44a8431f..95e4d400 100644 --- a/genetIC/src/io/gadget.hpp +++ b/genetIC/src/io/gadget.hpp @@ -273,7 +273,7 @@ namespace io { void saveGadgetBlock(particle::species forSpecies, std::function &)> getData) { - size_t current_n = 0; + size_t nTotalForThisBlock = 0; std::vector(std::declval()))> currentWriteBlocks; @@ -301,31 +301,39 @@ namespace io { for(int i=0; i(nPerFile[i])); + assert(this->template genericSaveBlock(particleTypes, getData, currentWriteBlocks) == nTotalForThisBlock); + + } + + template + size_t genericSaveBlock(const std::vector & particleTypes, + std::function &)> getData, + std::vector & currentWriteBlocks) { + size_t current_n = 0; + for (auto particle_type: particleTypes) { auto begin = mapper.beginParticleType(*generators[gadgetTypeToSpecies[particle_type]], particle_type); auto end = mapper.endParticleType(*generators[gadgetTypeToSpecies[particle_type]], particle_type); size_t nMax = end.getIndex() - begin.getIndex(); current_n += begin.parallelIterate( - [&](size_t n_offset, const particle::mapper::MapperIterator &localIterator) { - int fileNum = 0; - size_t addr = n_offset + current_n; - - // Now figure out which file to dump this into. - // The following approach looks slow (doing it for every particle!), - // but code profiling suggests it's not a significant overhead. - // Easier to do this than to try and have thread-local variables - while(addr >= nPartPerFile[fileNum]) { - addr-=nPartPerFile[fileNum]; - fileNum++; - } - - currentWriteBlocks[fileNum][addr] = getData(localIterator); - }, nMax); - + [&](size_t n_offset, const particle::mapper::MapperIterator &localIterator) { + int fileNum = 0; + size_t addr = n_offset + current_n; + + // Now figure out which file to dump this into. + // The following approach looks slow (doing it for every particle!), + // but code profiling suggests it's not a significant overhead. + // Easier to do this than to try and have thread-local variables + while (addr >= nPartPerFile[fileNum]) { + addr -= nPartPerFile[fileNum]; + fileNum++; + } + + currentWriteBlocks[fileNum][addr] = getData(localIterator); + }, nMax); } - - assert(current_n == nTotalForThisBlock); + return current_n; } @@ -401,8 +409,20 @@ namespace io { } + virtual void writeHeaderOneFile(size_t fileNumber, std::vector nPartPerTypeThisFile) { + if (gadgetVersion == 3) { + writers[fileNumber].writeFortran(createGadget3Header(masses, nPartPerTypeThisFile, nPartPerType, nFiles, + boxLength, cosmology)); + } else if (gadgetVersion == 2) { + writers[fileNumber].writeFortran(createGadget2Header(masses, nPartPerTypeThisFile, nPartPerType, nFiles, + boxLength, cosmology)); + } else { + throw std::runtime_error("Unknown gadget format"); + } + } + //! \brief Output the gadget3 or gadget2 header: - void writeHeader() { + virtual void writeHeader() { std::vector nPartPerTypeThisFile(6, 0); std::vector nPartRemainingPerType = nPartPerType; size_t offset = 0; @@ -433,15 +453,7 @@ namespace io { assert(nPartRemainingInFile == 0); // ensure we have assigned all the particles to a type - if (gadgetVersion == 3) { - writers[i].writeFortran(createGadget3Header(masses, nPartPerTypeThisFile, nPartPerType, nFiles, - boxLength, cosmology)); - } else if (gadgetVersion == 2) { - writers[i].writeFortran(createGadget2Header(masses, nPartPerTypeThisFile, nPartPerType, nFiles, - boxLength, cosmology)); - } else { - throw std::runtime_error("Unknown gadget format"); - } + writeHeaderOneFile(i, nPartPerTypeThisFile); this->nPartPerTypePerFile.push_back(nPartPerTypeThisFile); } @@ -481,7 +493,7 @@ namespace io { } //! \brief Operation to save gadget particles - void operator()(const std::string &name) { + virtual void operator()(const std::string &name) { preScanForMassesAndParticleNumbers(); diff --git a/genetIC/src/simulation/coordinate.hpp b/genetIC/src/simulation/coordinate.hpp index 452c37e2..7a6d4eb4 100644 --- a/genetIC/src/simulation/coordinate.hpp +++ b/genetIC/src/simulation/coordinate.hpp @@ -176,6 +176,18 @@ class Coordinate { }; +template +struct strip_coordinate { + public: + using type = T; +}; + +template +struct strip_coordinate> { + public: + using type = T; +}; + /*! \brief Iterates over all points in the window defined by the two co-ordinates, calling a function at each point. \param lowerCornerInclusive - lower left front corner of the window, including that point \param upperCornerExclusive - upper right back corner of the window, excluding that point diff --git a/tools/compare.py b/tools/compare.py index 3515838d..3f29d68b 100644 --- a/tools/compare.py +++ b/tools/compare.py @@ -29,6 +29,9 @@ def infer_compare_decimal(sim): return 4 def compare(f1,f2) : + assert f1.families() == f2.families() + for fam in f1.families(): + assert len(f1[fam])==len(f2[fam]) npt.assert_almost_equal(f1['mass'],f2['mass'],decimal=6) if 'eps' in f1.loadable_keys(): npt.assert_almost_equal(f1['eps'],f2['eps'],decimal=6) @@ -51,8 +54,9 @@ def compare(f1,f2) : if 'u' in f2.gas.loadable_keys(): # NB intentional to check for u in f2's loadable_keys # older versions of genetIC did not write 'u' with gas output - assert 'u' in f1.gas.loadable_keys() - npt.assert_almost_equal(f1.gas['u'], f2.gas['u'], decimal=5) + if not isinstance(f1, pynbody.snapshot.gadgethdf.GadgetHDFSnap): + assert 'u' in f1.gas.loadable_keys() + npt.assert_almost_equal(f1.gas['u'], f2.gas['u'], decimal=5) def post_compare_diagnostic_plot(f1,f2): import pylab as p @@ -61,12 +65,12 @@ def post_compare_diagnostic_plot(f1,f2): p.subplot(211) p.plot(f1['vx'], f2['vx']-f1['vx'], 'k,') p.xlabel("$v_x$") - p.ylabel("$\Delta v_x$") + p.ylabel(r"$\Delta v_x$") p.subplot(212) p.plot(f1['x'], f2['x']-f1['x'], 'k,') p.xlabel("$x$") - p.ylabel("$\Delta x$") + p.ylabel(r"$\Delta x$") p.savefig("diagnostic.png", bbox_inches='tight') p.close() @@ -196,10 +200,17 @@ def check_comparison_is_possible(dirname): def particle_files_in_dir(dirname): gadget_multifiles = glob.glob(dirname + "/*.gadget?.0") if len(gadget_multifiles) == 1: - gadget_multifiles = [gadget_multifiles[0][:-2]] - elif len(gadget_multifiles) > 1: - raise IOError("There is more than one particle output file to test against.") - return glob.glob(dirname + "/*.tipsy") + glob.glob(dirname + "/*.gadget?") + gadget_multifiles + gadget_multifiles = [f[:-2] for f in gadget_multifiles] + + hdf_multifiles = glob.glob(dirname + "/*.0.hdf5") + if len(hdf_multifiles) == 1: + hdf_multifiles = [f[:-7] for f in hdf_multifiles] + + hdf_files = glob.glob(dirname + "/*.hdf5") + hdf_files = [f for f in hdf_files if not any([f.startswith(h) for h in hdf_multifiles])] + + return (glob.glob(dirname + "/*.tipsy") + glob.glob(dirname + "/*.gadget?") + gadget_multifiles + + hdf_files + hdf_multifiles) def default_comparisons(): @@ -225,6 +236,8 @@ def default_comparisons(): compare_ps(ps,ps_test) output_file = particle_files_in_dir(sys.argv[1]) + if len(output_file)>1: + raise RuntimeError("More than one particle file to test against. Don't know which to use") if len(output_file)>0 and os.path.exists(sys.argv[1]+"/reference_output"): compare(pynbody.load(output_file[0]),pynbody.load(sys.argv[1]+"/reference_output")) From b88ea33e4fba3c4337a7792afeea9edc25d86e20 Mon Sep 17 00:00:00 2001 From: Andrew Pontzen Date: Tue, 16 Apr 2024 20:34:53 +0100 Subject: [PATCH 02/17] Add HDF5 to CI dependencies --- .github/workflows/build-test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index accef339..37b57a29 100644 --- a/.github/workflows/build-test.yaml +++ b/.github/workflows/build-test.yaml @@ -39,13 +39,13 @@ jobs: run: | sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt-get update -qq - sudo apt install libfftw3-dev libgsl0-dev + sudo apt install libfftw3-dev libgsl0-dev libhdf5-serial-dev sudo apt install gcc-10 g++-10 gcc-11 g++-11 gcc-12 g++-12 - name: Install dependencies if: matrix.os == 'macos-latest' shell: bash run: | - brew install gcc@12 fftw gsl + brew install gcc@12 fftw gsl hdf5 brew link gsl - name: Compile code working-directory: genetIC From d55f252aa0bdf3df91533d4a3c98251d9803b7d5 Mon Sep 17 00:00:00 2001 From: Andrew Pontzen Date: Tue, 16 Apr 2024 20:35:31 +0100 Subject: [PATCH 03/17] Add missing gadgethdf.hpp file --- genetIC/src/io/gadgethdf.hpp | 269 +++++++++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 genetIC/src/io/gadgethdf.hpp diff --git a/genetIC/src/io/gadgethdf.hpp b/genetIC/src/io/gadgethdf.hpp new file mode 100644 index 00000000..595d9375 --- /dev/null +++ b/genetIC/src/io/gadgethdf.hpp @@ -0,0 +1,269 @@ +#ifndef IC_GADGETHDF_HPP +#define IC_GADGETHDF_HPP + +#include "gadget.hpp" +#include "H5Cpp.h" + +namespace io { + /*! + \namespace io::gadget + \brief Classes related to outputting particle data in the gadget 2 and gadget 3 formats. +*/ + namespace gadgethdf { + + + using std::cerr; + using std::endl; + using std::vector; + + + /*! \class GadgetOutput + \brief Class to handle output to gadget files. + */ + template + class GadgetHDFOutput : public gadget::GadgetOutput { + protected: + using InternalFloatType = tools::datatypes::strip_complex; + std::vector h5Files; + + //! \brief Save a gadget block such as the mass or position arrays. + //! Takes a lambda (or other function) which, given a mapper iterator, returns the data to be written for that + //! particle. The writing proceeds in parallel using a memmap. + template + void saveGadgetHDFBlock(particle::species forSpecies, + std::function &)> getData) { + + } + + public: + + GadgetHDFOutput(double boxLength, + particle::mapper::ParticleMapper &mapper, + const particle::SpeciesToGeneratorMap &generators_, + const cosmology::CosmologicalParameters> &cosmology, + int numFiles) : + gadget::GadgetOutput(boxLength, mapper, generators_, + cosmology, 0, numFiles) { } + + template + constexpr const H5::PredType & getH5Type() { + if constexpr (std::is_same::value || std::is_same>::value) { + return H5::PredType::NATIVE_DOUBLE; + } else if constexpr (std::is_same::value || + std::is_same>::value) { + return H5::PredType::NATIVE_FLOAT; + } else if constexpr (std::is_same::value) { + return H5::PredType::NATIVE_ULONG; + } else if constexpr (std::is_same::value) { + return H5::PredType::NATIVE_HBOOL; + } else if constexpr(std::is_same::value) { + return H5::PredType::NATIVE_UINT; + } else { + static_assert(false, "Unknown type for HDF5 output"); + } + } + + template::type> + H5::DataSet createDataSet(H5::H5Location & location, std::string name, size_t nTotal) { + const bool three_dimensional = ~std::is_same::value; + + if constexpr(three_dimensional) { + static_assert(sizeof(Coordinate) == 3*sizeof(UnderlyingType)); + } + + int rank; + hsize_t dims_3d[2] = {nTotal, 3}; + hsize_t dims_1d[1] = {nTotal}; + hsize_t *dims; + + if(three_dimensional) { + rank = 2; + dims = dims_3d; + } else { + rank = 1; + dims = dims_1d; + } + + H5::DataSpace dataspace(rank, dims); + H5::DataSet dataset = location.createDataSet(name, getH5Type(), dataspace); + return dataset; + } + + + template + void saveBlock(particle::species forSpecies, + std::function &)> getData, + std::string name) { + + size_t current_n = 0; + size_t nTotalForThisBlock = 0; + + for(int particleType = 0; particleType < 6; particleType++) { + if (forSpecies != this->gadgetTypeToSpecies[particleType] && forSpecies != particle::species::all) + continue; + + std::vector groups; + std::vector datasets; + std::vector buffer; + + size_t nPartThisType = 0; + + // create or open particle type groups + for (int i=0; inFiles; i++) { + H5::H5File &file = h5Files[i]; + std::string groupName = "/PartType"+std::to_string(particleType); + size_t nPart = this->nPartPerTypePerFile[i][particleType]; + try { + groups.push_back(file.openGroup(groupName)); + } catch (H5::Exception &e) { + groups.push_back(file.createGroup(groupName)); + } + datasets.push_back(createDataSet(groups.back(), name, nPart)); + nPartThisType += nPart; + } + + assert(nPartThisType == this->nPartPerType[particleType]); + + buffer.resize(nPartThisType); + + auto begin = this->mapper.beginParticleType(*this->generators[this->gadgetTypeToSpecies[particleType]], + particleType); + auto end = this->mapper.endParticleType(*this->generators[this->gadgetTypeToSpecies[particleType]], + particleType); + begin.parallelIterate( + [&](size_t n_offset, const particle::mapper::MapperIterator &localIterator) { + buffer[n_offset] = getData(localIterator); + }, end - begin); + + size_t offset = 0; + for (int i = 0; i < this->nFiles; i++) { + datasets[i].write(&buffer[offset], getH5Type()); + offset+=this->nPartPerTypePerFile[i][particleType]; + } + } + + } + + template + void writeHdfAttributeArray(H5::Group & group, std::string name, const std::vector & value) { + hsize_t size[1] = {value.size()}; + auto & type = getH5Type(); + H5::Attribute attribute = group.createAttribute(name, type, H5::DataSpace(1, size)); + attribute.write(type, &value[0]); + } + + template + void writeHdfAttribute(H5::Group & group, std::string name, const T & value) { + auto & type = getH5Type(); + H5::Attribute attribute = group.createAttribute(name, type, H5::DataSpace(H5S_SCALAR)); + attribute.write(type, &value); + } + + virtual void writeHeaderOneFile(size_t fileNumber, std::vector nPartPerTypeThisFile) { + bool baryonic = (this->cosmology.OmegaBaryons0>0); + H5::Group headerGroup = h5Files[fileNumber].createGroup("/Header"); + writeHdfAttributeArray(headerGroup, "NumPart_ThisFile", nPartPerTypeThisFile); + writeHdfAttributeArray(headerGroup, "NumPart_Total", this->nPartPerType); + writeHdfAttributeArray(headerGroup, "MassTable", this->masses); + writeHdfAttribute(headerGroup, "ExpansionFactor", this->cosmology.scalefactor); + writeHdfAttribute(headerGroup, "Redshift", 1./this->cosmology.scalefactor-1.); + writeHdfAttribute(headerGroup, "HubbleParam", this->cosmology.hubble); + writeHdfAttribute(headerGroup, "Flag_Sfr", baryonic); + writeHdfAttribute(headerGroup, "Flag_Cooling", baryonic); + writeHdfAttribute(headerGroup, "Flag_Feedback", baryonic); + writeHdfAttribute(headerGroup, "Flag_StellarAge", baryonic); + writeHdfAttribute(headerGroup, "Flag_Metals", baryonic); + writeHdfAttribute(headerGroup, "BoxSize", this->boxLength); + writeHdfAttribute(headerGroup, "Omega0", this->cosmology.OmegaM0); + writeHdfAttribute(headerGroup, "OmegaLambda", this->cosmology.OmegaLambda0); + writeHdfAttribute(headerGroup, "Flag_DoublePrecision", std::is_same::value); + writeHdfAttribute(headerGroup, "NumFilesPerSnapshot", this->nFiles); + + + + } + + + //! \brief Operation to save gadget particles + virtual void operator()(const std::string &name) { + + H5::Exception::dontPrint(); + + this->preScanForMassesAndParticleNumbers(); + + if(this->nFiles==1) { + h5Files.push_back(H5::H5File(name + ".hdf5", H5F_ACC_TRUNC)); + } else { + for(int i=0; inFiles; i++) { + h5Files.push_back(H5::H5File(name + "." + std::to_string(i)+ ".hdf5", H5F_ACC_TRUNC)); + } + } + + + this->writeHeader(); + + + + saveBlock>( + particle::species::all, + [](auto &localIterator) { + auto particle = localIterator.getParticle(); + return Coordinate(particle.pos); + }, "Coordinates"); + + saveBlock>( + particle::species::all, + [](auto &localIterator) { + auto particle = localIterator.getParticle(); + return Coordinate(particle.vel); + }, "Velocities"); + + saveBlock( + particle::species::all, + [](auto &localIterator) { + return localIterator.getIndex(); + }, "ParticleIDs"); + + + if (this->variableMass) { + saveBlock( + particle::species::all, + [](auto &localIterator) { + return localIterator.getMass(); + }, "Masses"); + } + + + + + } + + + }; + + + //! \brief Generates gadget HDF output + /*! + \param name - name of output file + \param Boxlength - simulation size in Mpc/h + \param mapper - particle mapper used to link particles to grid locations + \param generators - particles generators for each particle species (vector) + \param cosmology - cosmological parameters + */ + template + void save(const std::string &name, double Boxlength, + particle::mapper::ParticleMapper &mapper, + particle::SpeciesToGeneratorMap &generators, + const cosmology::CosmologicalParameters> &cosmology, + int nFiles) { + + GadgetHDFOutput output(Boxlength, mapper, generators, cosmology, nFiles); + output(name); + + } + + } +} + + +#endif From e1045becd48e70d04279dff6794eeb2596033c68 Mon Sep 17 00:00:00 2001 From: Andrew Pontzen Date: Tue, 16 Apr 2024 22:55:58 +0100 Subject: [PATCH 04/17] Steps towards fixing use of hdf5 library --- genetIC/Dockerfile | 2 +- genetIC/Makefile | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/genetIC/Dockerfile b/genetIC/Dockerfile index 93fd7a14..4047072a 100644 --- a/genetIC/Dockerfile +++ b/genetIC/Dockerfile @@ -1,7 +1,7 @@ FROM ubuntu:20.04 COPY ./ /genetIC -RUN apt-get update && apt-get install -y g++-9 libgsl-dev libfftw3-dev python3-pip +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y g++-12 libgsl-dev libfftw3-dev python3-pip pkg-config libhdf5-serial-dev RUN pip3 install numpy pynbody RUN cd /genetIC && make clean && make diff --git a/genetIC/Makefile b/genetIC/Makefile index 359a8133..c30399e1 100644 --- a/genetIC/Makefile +++ b/genetIC/Makefile @@ -40,6 +40,11 @@ FFTWLIB = -lfftw3 -lfftw3f -lfftw3_threads HDFLIB = -lhdf5 -lhdf5_cpp +# if pkg-config is installed, add $(pkg-config --libs-only-L hdf5) to HDFLIB: +HDFLIB += $(shell pkg-config --libs-only-L hdf5) + +# add also $(pkg-config --cflags hdf5) to CFLAGS: +CFLAGS += $(shell pkg-config --cflags hdf5) # Provide information on the git repository, to be printed out on each run From e8e2e5addc2f17242e1f2d3f400b234e31c765c1 Mon Sep 17 00:00:00 2001 From: Andrew Pontzen Date: Wed, 17 Apr 2024 07:38:45 +0100 Subject: [PATCH 05/17] Correct way to stop instantiation of getH5Type without specialization --- genetIC/src/io/gadgethdf.hpp | 56 +++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/genetIC/src/io/gadgethdf.hpp b/genetIC/src/io/gadgethdf.hpp index 595d9375..7ba4571a 100644 --- a/genetIC/src/io/gadgethdf.hpp +++ b/genetIC/src/io/gadgethdf.hpp @@ -16,6 +16,44 @@ namespace io { using std::endl; using std::vector; + template + constexpr const H5::PredType & getH5Type(); + + template<> + constexpr const H5::PredType & getH5Type() { + return H5::PredType::NATIVE_FLOAT; + } + + template<> + constexpr const H5::PredType & getH5Type() { + return H5::PredType::NATIVE_DOUBLE; + } + + template<> + constexpr const H5::PredType & getH5Type() { + return H5::PredType::NATIVE_ULONG; + } + + template<> + constexpr const H5::PredType & getH5Type() { + return H5::PredType::NATIVE_HBOOL; + } + + template<> + constexpr const H5::PredType & getH5Type() { + return H5::PredType::NATIVE_UINT; + } + + template<> + constexpr const H5::PredType & getH5Type>() { + return getH5Type(); + } + + template<> + constexpr const H5::PredType & getH5Type>() { + return getH5Type(); + } + /*! \class GadgetOutput \brief Class to handle output to gadget files. @@ -45,23 +83,7 @@ namespace io { gadget::GadgetOutput(boxLength, mapper, generators_, cosmology, 0, numFiles) { } - template - constexpr const H5::PredType & getH5Type() { - if constexpr (std::is_same::value || std::is_same>::value) { - return H5::PredType::NATIVE_DOUBLE; - } else if constexpr (std::is_same::value || - std::is_same>::value) { - return H5::PredType::NATIVE_FLOAT; - } else if constexpr (std::is_same::value) { - return H5::PredType::NATIVE_ULONG; - } else if constexpr (std::is_same::value) { - return H5::PredType::NATIVE_HBOOL; - } else if constexpr(std::is_same::value) { - return H5::PredType::NATIVE_UINT; - } else { - static_assert(false, "Unknown type for HDF5 output"); - } - } + template::type> H5::DataSet createDataSet(H5::H5Location & location, std::string name, size_t nTotal) { From 6bd76c14ea074368117d1ad014d0b39838427a56 Mon Sep 17 00:00:00 2001 From: Andrew Pontzen Date: Wed, 17 Apr 2024 20:01:09 +0100 Subject: [PATCH 06/17] Try to fix CI build --- genetIC/Makefile | 8 +++----- genetIC/src/io.hpp | 2 +- genetIC/src/tools/numerics/fourier.hpp | 1 - 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/genetIC/Makefile b/genetIC/Makefile index c30399e1..754a3405 100644 --- a/genetIC/Makefile +++ b/genetIC/Makefile @@ -38,10 +38,8 @@ GSLFLAGS = -lgsl -lgslcblas FFTW = -DFFTW3 -DFFTW_THREADS FFTWLIB = -lfftw3 -lfftw3f -lfftw3_threads -HDFLIB = -lhdf5 -lhdf5_cpp - # if pkg-config is installed, add $(pkg-config --libs-only-L hdf5) to HDFLIB: -HDFLIB += $(shell pkg-config --libs-only-L hdf5) +HDFLIB = $(shell pkg-config --libs-only-L hdf5) -lhdf5 -lhdf5_cpp # add also $(pkg-config --cflags hdf5) to CFLAGS: CFLAGS += $(shell pkg-config --cflags hdf5) @@ -95,7 +93,7 @@ ifeq ($(HOST), clema) endif ifeq ($(HOST), butte) - CXX = /opt/homebrew/Cellar/llvm/17.0.6_1/bin/clang++ + CXX = g++-12 # /opt/homebrew/Cellar/llvm/17.0.6_1/bin/clang++ CPATH = /opt/homebrew/include/ LPATH = /opt/homebrew/lib/ endif @@ -149,7 +147,7 @@ all: genetIC %.o: %.cpp ; $(CXX) $(CFLAGS) $(CODEOPTIONS) $(GIT_VARIABLES) -I$(CPATH) $(FFTW) -c $< -o $@ genetIC: src/main.o src/tools/filesystem.o src/tools/progress/progress.o src/tools/logging.o - $(CXX) $(CFLAGS) -o genetIC $(GIT_VARIABLES) -I$(CPATH) $(FFTW) $(HDFLIB) src/main.o src/tools/filesystem.o src/tools/progress/progress.o src/tools/logging.o -L$(LPATH) $(GSLFLAGS) -lm $(FFTWLIB) + $(CXX) $(CFLAGS) -o genetIC $(GIT_VARIABLES) -I$(CPATH) $(FFTW) src/main.o src/tools/filesystem.o src/tools/progress/progress.o src/tools/logging.o -L$(LPATH) $(GSLFLAGS) -lm $(FFTWLIB) $(HDFLIB) clean: rm -f genetIC diff --git a/genetIC/src/io.hpp b/genetIC/src/io.hpp index e0f0460a..157e6c6b 100644 --- a/genetIC/src/io.hpp +++ b/genetIC/src/io.hpp @@ -65,7 +65,7 @@ namespace io { try { int i = std::stoi(s); format = static_cast(i); - } catch (std::invalid_argument e) { + } catch (const std::invalid_argument & e) { if (s == "gadget2") { format = OutputFormat::gadget2; } else if (s == "gadget3") { diff --git a/genetIC/src/tools/numerics/fourier.hpp b/genetIC/src/tools/numerics/fourier.hpp index 4088a8c3..670ad913 100644 --- a/genetIC/src/tools/numerics/fourier.hpp +++ b/genetIC/src/tools/numerics/fourier.hpp @@ -16,7 +16,6 @@ #endif #include -#include #include "src/simulation/coordinate.hpp" #include "src/tools/data_types/complex.hpp" From bf55799f08786d5849b84643963b73f943e59f2e Mon Sep 17 00:00:00 2001 From: Andrew Pontzen Date: Wed, 17 Apr 2024 20:07:50 +0100 Subject: [PATCH 07/17] Add tests for GadgetHDF --- .github/workflows/build-test.yaml | 2 +- genetIC/tests/test_26_gadgethdf/paramfile.txt | 22 +++++++++++++ .../tests/test_26_gadgethdf/reference_output | Bin 0 -> 16672 bytes .../paramfile.txt | 31 ++++++++++++++++++ .../reference_output | Bin 0 -> 212272 bytes 5 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 genetIC/tests/test_26_gadgethdf/paramfile.txt create mode 100644 genetIC/tests/test_26_gadgethdf/reference_output create mode 100644 genetIC/tests/test_26a_gadgethdf_multifile_baryons/paramfile.txt create mode 100644 genetIC/tests/test_26a_gadgethdf_multifile_baryons/reference_output diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index 37b57a29..2d3af3e5 100644 --- a/.github/workflows/build-test.yaml +++ b/.github/workflows/build-test.yaml @@ -56,7 +56,7 @@ jobs: export CC=gcc-10 python -m pip install --upgrade pip setuptools wheel python -m pip install numpy scipy cython - python -m pip install pynbody + python -m pip install --pre pynbody - name: Run tests shell: bash working-directory: genetIC/tests diff --git a/genetIC/tests/test_26_gadgethdf/paramfile.txt b/genetIC/tests/test_26_gadgethdf/paramfile.txt new file mode 100644 index 00000000..2505d968 --- /dev/null +++ b/genetIC/tests/test_26_gadgethdf/paramfile.txt @@ -0,0 +1,22 @@ +# Test basic uniform volume with gadget output + +Om 0.279 +Ol 0.721 +#Ob 0.04 +s8 0.817 +zin 99 + +random_seed_real_space 8896131 +camb ../camb_transfer_kmax40_z0.dat + +outname test +outdir ./ +outformat gadgethdf + + +basegrid 50.0 8 + + + + +done diff --git a/genetIC/tests/test_26_gadgethdf/reference_output b/genetIC/tests/test_26_gadgethdf/reference_output new file mode 100644 index 0000000000000000000000000000000000000000..a1413aa80ce1312eec58b129edd3aaeff1084ad6 GIT binary patch literal 16672 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

>?_4rMc1IvnwRLfU&Eg3 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�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 Date: Wed, 17 Apr 2024 20:22:05 +0100 Subject: [PATCH 08/17] Attempt to fix CI build on macos --- .github/workflows/build-test.yaml | 5 +++-- genetIC/Makefile | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index 2d3af3e5..b3d0b159 100644 --- a/.github/workflows/build-test.yaml +++ b/.github/workflows/build-test.yaml @@ -23,7 +23,8 @@ jobs: include: - os: macos-latest python-version: "3.10" - cxx: g++-12 + cxx: /opt/homebrew/opt/llvm/bin/clang++ + # gcc won't work because homebrew's hdf5_cpp is built against apple's clang C++ library runs-on: ${{ matrix.os }} env: CXX: ${{ matrix.cxx }} @@ -45,7 +46,7 @@ jobs: if: matrix.os == 'macos-latest' shell: bash run: | - brew install gcc@12 fftw gsl hdf5 + brew install llvm fftw gsl hdf5 brew link gsl - name: Compile code working-directory: genetIC diff --git a/genetIC/Makefile b/genetIC/Makefile index 754a3405..af4f411b 100644 --- a/genetIC/Makefile +++ b/genetIC/Makefile @@ -93,7 +93,7 @@ ifeq ($(HOST), clema) endif ifeq ($(HOST), butte) - CXX = g++-12 # /opt/homebrew/Cellar/llvm/17.0.6_1/bin/clang++ + CXX = /opt/homebrew/Cellar/llvm/17.0.6_1/bin/clang++ CPATH = /opt/homebrew/include/ LPATH = /opt/homebrew/lib/ endif From 4611987c6189ced2f5518e2f0864389e2eb0517a Mon Sep 17 00:00:00 2001 From: Andrew Pontzen Date: Wed, 17 Apr 2024 20:26:14 +0100 Subject: [PATCH 09/17] Fix path to homebrew on x86 macs --- .github/workflows/build-test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index b3d0b159..3db3bd91 100644 --- a/.github/workflows/build-test.yaml +++ b/.github/workflows/build-test.yaml @@ -23,7 +23,7 @@ jobs: include: - os: macos-latest python-version: "3.10" - cxx: /opt/homebrew/opt/llvm/bin/clang++ + cxx: /usr/local/opt/llvm/bin/clang++ # gcc won't work because homebrew's hdf5_cpp is built against apple's clang C++ library runs-on: ${{ matrix.os }} env: From e4c88e2690db5947c95dc1930ce3b632a3046eeb Mon Sep 17 00:00:00 2001 From: Andrew Pontzen Date: Wed, 17 Apr 2024 20:33:34 +0100 Subject: [PATCH 10/17] Attempt CI build with Apple stock clang --- .github/workflows/build-test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index 3db3bd91..001aaec3 100644 --- a/.github/workflows/build-test.yaml +++ b/.github/workflows/build-test.yaml @@ -23,7 +23,7 @@ jobs: include: - os: macos-latest python-version: "3.10" - cxx: /usr/local/opt/llvm/bin/clang++ + cxx: clang++ # gcc won't work because homebrew's hdf5_cpp is built against apple's clang C++ library runs-on: ${{ matrix.os }} env: @@ -46,7 +46,7 @@ jobs: if: matrix.os == 'macos-latest' shell: bash run: | - brew install llvm fftw gsl hdf5 + brew install fftw gsl hdf5 brew link gsl - name: Compile code working-directory: genetIC From 12ad24910db72f875e4452f4e9c117d72bf78d81 Mon Sep 17 00:00:00 2001 From: Andrew Pontzen Date: Thu, 18 Apr 2024 20:49:32 +0100 Subject: [PATCH 11/17] Attempt to fix issues with installation on MacOS Unfortunately using HDF5's own C++ library is very complicated because i) It is linked against (probably) Apple's own libc++ ii) This means one cannot link it from g++ because g++'s STL expects different ABI iii) But Apple's own clang does not have OpenMP iv) If one tries to use homebrew clang, one gets mysterious errors, probably due to slightly different clang libc++ versions So, instead, I have migrated to a different HDF C++ wrapper (which anyway seems far better written) --- .github/workflows/build-test.yaml | 7 +- .gitmodules | 4 + CMakeLists.txt | 7 +- genetIC/HighFive | 1 + genetIC/Makefile | 15 ++-- genetIC/src/io/gadgethdf.hpp | 117 ++++++++---------------------- 6 files changed, 55 insertions(+), 96 deletions(-) create mode 100644 .gitmodules create mode 160000 genetIC/HighFive diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index 001aaec3..9f0623ca 100644 --- a/.github/workflows/build-test.yaml +++ b/.github/workflows/build-test.yaml @@ -23,8 +23,7 @@ jobs: include: - os: macos-latest python-version: "3.10" - cxx: clang++ - # gcc won't work because homebrew's hdf5_cpp is built against apple's clang C++ library + cxx: g++-12 runs-on: ${{ matrix.os }} env: CXX: ${{ matrix.cxx }} @@ -34,6 +33,8 @@ jobs: with: python-version: ${{ matrix.python-version }} - uses: actions/checkout@v2 + with: + submodules: recursive - name: Install dependencies if: matrix.os == 'ubuntu-latest' shell: bash @@ -46,7 +47,7 @@ jobs: if: matrix.os == 'macos-latest' shell: bash run: | - brew install fftw gsl hdf5 + brew install gcc@12 fftw gsl hdf5 brew link gsl - name: Compile code working-directory: genetIC diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..41773f27 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "genetIC/HighFive"] + path = genetIC/HighFive + url = https://github.com/BlueBrain/HighFive + branch = v2.9.0 diff --git a/CMakeLists.txt b/CMakeLists.txt index 73353b22..10b8f977 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.2) project(IC) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/genetIC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -g ") @@ -64,10 +65,14 @@ set(SOURCE_FILES genetIC/src/tools/memmap.hpp genetIC/src/tools/numerics/tricubic.hpp genetIC/src/tools/logging.hpp genetIC/src/tools/logging.cpp genetIC/src/simulation/modifications/splice.hpp genetIC/src/tools/lru_cache.hpp) +include_directories(/opt/homebrew/include) +link_directories(/opt/homebrew/lib) include_directories( /opt/local/include ) link_directories(/opt/local/lib ) + include_directories( genetIC/ ) -link_libraries(fftw3 m fftw3f fftw3_threads gsl gslcblas hdf5 hdf5_cpp) +include_directories( genetIC/HighFive/include ) +link_libraries(fftw3 m fftw3f fftw3_threads gsl gslcblas hdf5 ) exec_program( diff --git a/genetIC/HighFive b/genetIC/HighFive new file mode 160000 index 00000000..0d0259e8 --- /dev/null +++ b/genetIC/HighFive @@ -0,0 +1 @@ +Subproject commit 0d0259e823a0e8aee2f036ba738c703ac4a0721c diff --git a/genetIC/Makefile b/genetIC/Makefile index af4f411b..cc39ddf8 100644 --- a/genetIC/Makefile +++ b/genetIC/Makefile @@ -1,5 +1,5 @@ # Reasonably sensible defaults -CFLAGS ?= -Wall -g -lpthread -O3 -fopenmp -std=c++17 -fdiagnostics-color=auto -I`pwd` +CFLAGS ?= -Wall -g -lpthread -O3 -fopenmp -std=c++17 -fdiagnostics-color=auto -I`pwd` -I`pwd`/HighFive/include # Here are code options. Probably don't fiddle with these unless you know what you're doing. # @@ -65,14 +65,14 @@ ifeq ($(USE_CUFFT), 1) FFTW = -DFFTW3 FFTWLIB = -lcufft -lcufftw OLD_CFLAGS=$(CFLAGS) - CFLAGS=-O3 -I`pwd` -Xcompiler="-O3 -fopenmp -std=c++14 -Wall" + CFLAGS=-O3 -I`pwd` -I`pwd`/HighFive/include -Xcompiler="-O3 -fopenmp -std=c++14 -Wall" CXX=nvcc endif ifeq ($(HOST3), pfe) CXX = /nasa/pkgsrc/2016Q2/gcc5/bin/g++ CPATH = /u/apontzen/genetIC/genetIC:/nasa/gsl/1.14/include/:/nasa/intel/Compiler/2016.2.181/compilers_and_libraries_2016.2.181/linux/mkl/include/fftw LPATH = /nasa/gsl/1.14/lib/ -L/nasa/intel/Compiler/2016.2.181/compilers_and_libraries_2016.2.181/linux/mkl/lib/intel64/ - CFLAGS = -Wall -g -O3 -fopenmp -std=c++17 -fdiagnostics-color=auto -I`pwd` -DOPENMP -DDOUBLEPRECISION + CFLAGS = -Wall -g -O3 -fopenmp -std=c++17 -fdiagnostics-color=auto -I`pwd` -I`pwd`/HighFive/include -DOPENMP -DDOUBLEPRECISION FFTWLIB = -ldl -lpthread -lm -lstdc++ -lgfortran -lmkl_intel_ilp64 -lmkl_gnu_thread -lmkl_core FFTW = -DFFTW3 -DFFTW_THREADS GSLFLAGS = /nasa/gsl/1.14/lib/libgsl.a /nasa/gsl/1.14/lib/libgslcblas.a @@ -81,26 +81,27 @@ endif ifeq ($(HOST), Snowd) CPATH = /opt/local/include/ LPATH = /opt/local/lib/ - CFLAGS = -O3 -fopenmp -std=c++17 -fdiagnostics-color=auto -I`pwd` -DOPENMP -DDOUBLEPRECISION + CFLAGS = -O3 -fopenmp -std=c++17 -fdiagnostics-color=auto -I`pwd` -I`pwd`/HighFive/include -DOPENMP -DDOUBLEPRECISION CXX = /opt/local/bin/clang++-mp-6.0 endif ifeq ($(HOST), clema) CPATH = /opt/local/include/ LPATH = /opt/local/lib/ - CFLAGS = -O2 -g -fopenmp -std=c++17 -fdiagnostics-color=auto -I`pwd` -DOPENMP -DDOUBLEPRECISION + CFLAGS = -O2 -g -fopenmp -std=c++17 -fdiagnostics-color=auto -I`pwd` -I`pwd`/HighFive/include -DOPENMP -DDOUBLEPRECISION CXX = /opt/local/bin/clang++-mp-6.0 endif ifeq ($(HOST), butte) - CXX = /opt/homebrew/Cellar/llvm/17.0.6_1/bin/clang++ + CXX = g++-13 CPATH = /opt/homebrew/include/ LPATH = /opt/homebrew/lib/ + CFLAGS += -Wl,-ld_classic # new macOS linker doesn't like C++, see XCode bug FB13097713 endif ifeq ($(HOST), jasmi) CXX = /opt/local/bin/g++-mp-11 -L/opt/local/lib/ - CFLAGS = -O3 -g -fopenmp -std=c++17 -I`pwd` -DOPENMP -DDOUBLEPRECISION + CFLAGS = -O3 -g -fopenmp -std=c++17 -I`pwd` -I`pwd`/HighFive/include -DOPENMP -DDOUBLEPRECISION endif ifeq ($(HOST), Rhodo) diff --git a/genetIC/src/io/gadgethdf.hpp b/genetIC/src/io/gadgethdf.hpp index 7ba4571a..5c59c597 100644 --- a/genetIC/src/io/gadgethdf.hpp +++ b/genetIC/src/io/gadgethdf.hpp @@ -2,7 +2,11 @@ #define IC_GADGETHDF_HPP #include "gadget.hpp" -#include "H5Cpp.h" + +// we use this third-party HDF C++ wrapper because it is more modern and doesn't require +// a binary C++ dylib. The C++ dylib causes major problems on macos trying to get everything +// to link correctly (e.g. GNU vs clang libstdc++ issues) +#include namespace io { /*! @@ -16,44 +20,6 @@ namespace io { using std::endl; using std::vector; - template - constexpr const H5::PredType & getH5Type(); - - template<> - constexpr const H5::PredType & getH5Type() { - return H5::PredType::NATIVE_FLOAT; - } - - template<> - constexpr const H5::PredType & getH5Type() { - return H5::PredType::NATIVE_DOUBLE; - } - - template<> - constexpr const H5::PredType & getH5Type() { - return H5::PredType::NATIVE_ULONG; - } - - template<> - constexpr const H5::PredType & getH5Type() { - return H5::PredType::NATIVE_HBOOL; - } - - template<> - constexpr const H5::PredType & getH5Type() { - return H5::PredType::NATIVE_UINT; - } - - template<> - constexpr const H5::PredType & getH5Type>() { - return getH5Type(); - } - - template<> - constexpr const H5::PredType & getH5Type>() { - return getH5Type(); - } - /*! \class GadgetOutput \brief Class to handle output to gadget files. @@ -62,16 +28,7 @@ namespace io { class GadgetHDFOutput : public gadget::GadgetOutput { protected: using InternalFloatType = tools::datatypes::strip_complex; - std::vector h5Files; - - //! \brief Save a gadget block such as the mass or position arrays. - //! Takes a lambda (or other function) which, given a mapper iterator, returns the data to be written for that - //! particle. The writing proceeds in parallel using a memmap. - template - void saveGadgetHDFBlock(particle::species forSpecies, - std::function &)> getData) { - - } + std::vector h5Files; public: @@ -86,28 +43,19 @@ namespace io { template::type> - H5::DataSet createDataSet(H5::H5Location & location, std::string name, size_t nTotal) { - const bool three_dimensional = ~std::is_same::value; + HighFive::DataSet createDataSet(HighFive::Group & location, std::string name, size_t nTotal) { + const bool three_dimensional = !std::is_same::value; + + std::unique_ptr ds; if constexpr(three_dimensional) { static_assert(sizeof(Coordinate) == 3*sizeof(UnderlyingType)); - } - - int rank; - hsize_t dims_3d[2] = {nTotal, 3}; - hsize_t dims_1d[1] = {nTotal}; - hsize_t *dims; - - if(three_dimensional) { - rank = 2; - dims = dims_3d; + ds = std::make_unique(nTotal, 3); } else { - rank = 1; - dims = dims_1d; + ds = std::make_unique(nTotal); } - H5::DataSpace dataspace(rank, dims); - H5::DataSet dataset = location.createDataSet(name, getH5Type(), dataspace); + HighFive::DataSet dataset = location.createDataSet(name, *ds); return dataset; } @@ -117,6 +65,8 @@ namespace io { std::function &)> getData, std::string name) { + using UnderlyingType = typename strip_coordinate::type; + size_t current_n = 0; size_t nTotalForThisBlock = 0; @@ -124,20 +74,20 @@ namespace io { if (forSpecies != this->gadgetTypeToSpecies[particleType] && forSpecies != particle::species::all) continue; - std::vector groups; - std::vector datasets; + std::vector groups; + std::vector datasets; std::vector buffer; size_t nPartThisType = 0; // create or open particle type groups for (int i=0; inFiles; i++) { - H5::H5File &file = h5Files[i]; + HighFive::File &file = h5Files[i]; std::string groupName = "/PartType"+std::to_string(particleType); size_t nPart = this->nPartPerTypePerFile[i][particleType]; try { - groups.push_back(file.openGroup(groupName)); - } catch (H5::Exception &e) { + groups.push_back(file.getGroup(groupName)); + } catch (HighFive::Exception &e) { groups.push_back(file.createGroup(groupName)); } datasets.push_back(createDataSet(groups.back(), name, nPart)); @@ -159,7 +109,7 @@ namespace io { size_t offset = 0; for (int i = 0; i < this->nFiles; i++) { - datasets[i].write(&buffer[offset], getH5Type()); + datasets[i].write_raw(reinterpret_cast(&buffer[offset])); offset+=this->nPartPerTypePerFile[i][particleType]; } } @@ -167,23 +117,21 @@ namespace io { } template - void writeHdfAttributeArray(H5::Group & group, std::string name, const std::vector & value) { - hsize_t size[1] = {value.size()}; - auto & type = getH5Type(); - H5::Attribute attribute = group.createAttribute(name, type, H5::DataSpace(1, size)); - attribute.write(type, &value[0]); + void writeHdfAttributeArray(HighFive::Group & group, std::string name, const std::vector & value) { + HighFive::Attribute attribute = group.createAttribute(name, HighFive::DataSpace(value.size())); + attribute.write( value); } template - void writeHdfAttribute(H5::Group & group, std::string name, const T & value) { - auto & type = getH5Type(); - H5::Attribute attribute = group.createAttribute(name, type, H5::DataSpace(H5S_SCALAR)); - attribute.write(type, &value); + void writeHdfAttribute(HighFive::Group & group, std::string name, const T & value) { + HighFive::Attribute attribute = group.createAttribute(name, + HighFive::DataSpace(HighFive::DataSpace::DataspaceType::dataspace_scalar)); + attribute.write( value); } virtual void writeHeaderOneFile(size_t fileNumber, std::vector nPartPerTypeThisFile) { bool baryonic = (this->cosmology.OmegaBaryons0>0); - H5::Group headerGroup = h5Files[fileNumber].createGroup("/Header"); + HighFive::Group headerGroup = h5Files[fileNumber].createGroup("/Header"); writeHdfAttributeArray(headerGroup, "NumPart_ThisFile", nPartPerTypeThisFile); writeHdfAttributeArray(headerGroup, "NumPart_Total", this->nPartPerType); writeHdfAttributeArray(headerGroup, "MassTable", this->masses); @@ -209,15 +157,13 @@ namespace io { //! \brief Operation to save gadget particles virtual void operator()(const std::string &name) { - H5::Exception::dontPrint(); - this->preScanForMassesAndParticleNumbers(); if(this->nFiles==1) { - h5Files.push_back(H5::H5File(name + ".hdf5", H5F_ACC_TRUNC)); + h5Files.push_back(HighFive::File(name + ".hdf5", HighFive::File::Truncate)); } else { for(int i=0; inFiles; i++) { - h5Files.push_back(H5::H5File(name + "." + std::to_string(i)+ ".hdf5", H5F_ACC_TRUNC)); + h5Files.push_back(HighFive::File(name + "." + std::to_string(i)+ ".hdf5", HighFive::File::Truncate)); } } @@ -279,6 +225,7 @@ namespace io { const cosmology::CosmologicalParameters> &cosmology, int nFiles) { + HighFive::SilenceHDF5 silence; // suppresses HDF5 warnings while in scope GadgetHDFOutput output(Boxlength, mapper, generators, cosmology, nFiles); output(name); From 2edf4c5913430e632c22bbbb5db131d8b8677e37 Mon Sep 17 00:00:00 2001 From: Andrew Pontzen Date: Thu, 18 Apr 2024 21:36:36 +0100 Subject: [PATCH 12/17] Fix compilers for pynbody build (probably only used for posix_ipc) --- .github/workflows/build-test.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index 9f0623ca..d43c0241 100644 --- a/.github/workflows/build-test.yaml +++ b/.github/workflows/build-test.yaml @@ -55,7 +55,8 @@ jobs: - name: Install python dependencies shell: bash run: | - export CC=gcc-10 + export CC=gcc-12 + export CXX=g++-12 python -m pip install --upgrade pip setuptools wheel python -m pip install numpy scipy cython python -m pip install --pre pynbody From e3fc1a28eeac79b2e72f9093ea86b09d33e6e473 Mon Sep 17 00:00:00 2001 From: Andrew Pontzen Date: Thu, 18 Apr 2024 22:45:40 +0100 Subject: [PATCH 13/17] Remove now unused hdf5_cpp library --- genetIC/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/genetIC/Makefile b/genetIC/Makefile index cc39ddf8..b72aa3dd 100644 --- a/genetIC/Makefile +++ b/genetIC/Makefile @@ -39,7 +39,7 @@ FFTW = -DFFTW3 -DFFTW_THREADS FFTWLIB = -lfftw3 -lfftw3f -lfftw3_threads # if pkg-config is installed, add $(pkg-config --libs-only-L hdf5) to HDFLIB: -HDFLIB = $(shell pkg-config --libs-only-L hdf5) -lhdf5 -lhdf5_cpp +HDFLIB = $(shell pkg-config --libs-only-L hdf5) -lhdf5 # add also $(pkg-config --cflags hdf5) to CFLAGS: CFLAGS += $(shell pkg-config --cflags hdf5) From 3b078a381e706d77cab0e7591cc982cc850f90b1 Mon Sep 17 00:00:00 2001 From: Andrew Pontzen Date: Sat, 20 Apr 2024 10:53:33 +0100 Subject: [PATCH 14/17] Get gadgethdf output working with gadget 4 --- genetIC/Makefile | 2 +- genetIC/src/io/gadgethdf.hpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/genetIC/Makefile b/genetIC/Makefile index b72aa3dd..dac0c361 100644 --- a/genetIC/Makefile +++ b/genetIC/Makefile @@ -100,7 +100,7 @@ ifeq ($(HOST), butte) endif ifeq ($(HOST), jasmi) - CXX = /opt/local/bin/g++-mp-11 -L/opt/local/lib/ + CXX = /opt/local/bin/g++-mp-13 -L/opt/local/lib/ CFLAGS = -O3 -g -fopenmp -std=c++17 -I`pwd` -I`pwd`/HighFive/include -DOPENMP -DDOUBLEPRECISION endif diff --git a/genetIC/src/io/gadgethdf.hpp b/genetIC/src/io/gadgethdf.hpp index 5c59c597..b04481d1 100644 --- a/genetIC/src/io/gadgethdf.hpp +++ b/genetIC/src/io/gadgethdf.hpp @@ -137,6 +137,7 @@ namespace io { writeHdfAttributeArray(headerGroup, "MassTable", this->masses); writeHdfAttribute(headerGroup, "ExpansionFactor", this->cosmology.scalefactor); writeHdfAttribute(headerGroup, "Redshift", 1./this->cosmology.scalefactor-1.); + writeHdfAttribute(headerGroup, "Time", 0.0); // Gadget4 expects this but doesn't use it writeHdfAttribute(headerGroup, "HubbleParam", this->cosmology.hubble); writeHdfAttribute(headerGroup, "Flag_Sfr", baryonic); writeHdfAttribute(headerGroup, "Flag_Cooling", baryonic); From 2a12b562d91a744e3efbb8774bed706f713e672d Mon Sep 17 00:00:00 2001 From: Andrew Pontzen Date: Sat, 20 Apr 2024 22:37:39 +0100 Subject: [PATCH 15/17] Adapt gadgethdf output for swift --- CMakeLists.txt | 3 ++- genetIC/src/ic.hpp | 4 +++ genetIC/src/io.hpp | 10 ++++++-- genetIC/src/io/gadget.hpp | 7 +++-- genetIC/src/io/gadgethdf.hpp | 21 +++++++++++++-- genetIC/src/io/swift.hpp | 50 ++++++++++++++++++++++++++++++++++++ 6 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 genetIC/src/io/swift.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 10b8f977..b772ebaf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,7 +63,8 @@ set(SOURCE_FILES genetIC/src/simulation/modifications/quadraticmodification.hpp genetIC/src/simulation/multilevelgrid/mask.hpp genetIC/src/tools/memmap.hpp - genetIC/src/tools/numerics/tricubic.hpp genetIC/src/tools/logging.hpp genetIC/src/tools/logging.cpp genetIC/src/simulation/modifications/splice.hpp genetIC/src/tools/lru_cache.hpp) + genetIC/src/tools/numerics/tricubic.hpp genetIC/src/tools/logging.hpp genetIC/src/tools/logging.cpp genetIC/src/simulation/modifications/splice.hpp genetIC/src/tools/lru_cache.hpp + genetIC/src/io/swift.hpp) include_directories(/opt/homebrew/include) link_directories(/opt/homebrew/lib) diff --git a/genetIC/src/ic.hpp b/genetIC/src/ic.hpp index d4d6bbaa..939ecc27 100644 --- a/genetIC/src/ic.hpp +++ b/genetIC/src/ic.hpp @@ -1289,6 +1289,10 @@ class ICGenerator { gadgethdf::save(getOutputPath(), boxlen, *pMapper, pParticleGenerator, cosmology, nGadgetFiles); break; + case OutputFormat::swift: + swift::save(getOutputPath(), boxlen, *pMapper, pParticleGenerator, cosmology, + nGadgetFiles); + break; case OutputFormat::tipsy: tipsy::save(getOutputPath() + ".tipsy", boxlen, pParticleGenerator, diff --git a/genetIC/src/io.hpp b/genetIC/src/io.hpp index 157e6c6b..026d0f35 100644 --- a/genetIC/src/io.hpp +++ b/genetIC/src/io.hpp @@ -16,6 +16,7 @@ namespace cosmology { #include "io/input.hpp" #include "io/gadget.hpp" #include "io/gadgethdf.hpp" +#include "io/swift.hpp" #include "io/tipsy.hpp" #include "io/grafic.hpp" @@ -32,7 +33,7 @@ namespace cosmology { namespace io { enum class OutputFormat { - unknown = 1, gadget2 = 2, gadget3 = 3, tipsy = 4, grafic = 5, gadgethdf = 6 + unknown = 1, gadget2 = 2, gadget3 = 3, tipsy = 4, grafic = 5, gadgethdf = 6, swift = 7 }; std::ostream &operator<<(std::ostream &outputStream, const OutputFormat &format) { @@ -55,6 +56,9 @@ namespace io { case OutputFormat::gadgethdf: outputStream << "gadgethdf"; break; + case OutputFormat::swift: + outputStream << "swift"; + break; } return outputStream; } @@ -76,8 +80,10 @@ namespace io { format = OutputFormat::grafic; } else if (s == "gadgethdf") { format = OutputFormat::gadgethdf; + } else if (s == "swift") { + format = OutputFormat::swift; } else { - inputStream.setstate(std::ios::failbit); + inputStream.setstate(std::ios::failbit); } } return inputStream; diff --git a/genetIC/src/io/gadget.hpp b/genetIC/src/io/gadget.hpp index 95e4d400..489fdbc4 100644 --- a/genetIC/src/io/gadget.hpp +++ b/genetIC/src/io/gadget.hpp @@ -337,9 +337,12 @@ namespace io { } + //! \brief Returns false in base class. Override in child class to force variable mass output + virtual bool forceVariableMass() const { return false; } + //! \brief Scan through data to obtain information on particles and their masses. - void preScanForMassesAndParticleNumbers() { - variableMass = false; + virtual void preScanForMassesAndParticleNumbers() { + variableMass = this->forceVariableMass(); masses = vector(6, 0.0); nPartPerType = vector(6, 0); nTotal = 0; diff --git a/genetIC/src/io/gadgethdf.hpp b/genetIC/src/io/gadgethdf.hpp index b04481d1..333597cd 100644 --- a/genetIC/src/io/gadgethdf.hpp +++ b/genetIC/src/io/gadgethdf.hpp @@ -122,6 +122,18 @@ namespace io { attribute.write( value); } + template::value>::type> + void writeHdfAttributeArray32bit(HighFive::Group & group, std::string name, const std::vector & value) { + std::vector value_loword(value.size()); + std::vector value_hiword(value.size()); + for(size_t i=0; i(value[i] & 0xFFFFFFFF); + value_hiword[i] = static_cast(value[i] >> 32); + } + writeHdfAttributeArray(group, name, value_loword); + writeHdfAttributeArray(group, name+"_HighWord", value_hiword); + } + template void writeHdfAttribute(HighFive::Group & group, std::string name, const T & value) { HighFive::Attribute attribute = group.createAttribute(name, @@ -132,8 +144,12 @@ namespace io { virtual void writeHeaderOneFile(size_t fileNumber, std::vector nPartPerTypeThisFile) { bool baryonic = (this->cosmology.OmegaBaryons0>0); HighFive::Group headerGroup = h5Files[fileNumber].createGroup("/Header"); - writeHdfAttributeArray(headerGroup, "NumPart_ThisFile", nPartPerTypeThisFile); - writeHdfAttributeArray(headerGroup, "NumPart_Total", this->nPartPerType); + + // the following two are automatically split out into low and high words (since gadget4 can't + // cope with reading a 64-bit integer?!) + writeHdfAttributeArray32bit(headerGroup, "NumPart_ThisFile", nPartPerTypeThisFile); + writeHdfAttributeArray32bit(headerGroup, "NumPart_Total", this->nPartPerType); + writeHdfAttributeArray(headerGroup, "MassTable", this->masses); writeHdfAttribute(headerGroup, "ExpansionFactor", this->cosmology.scalefactor); writeHdfAttribute(headerGroup, "Redshift", 1./this->cosmology.scalefactor-1.); @@ -144,6 +160,7 @@ namespace io { writeHdfAttribute(headerGroup, "Flag_Feedback", baryonic); writeHdfAttribute(headerGroup, "Flag_StellarAge", baryonic); writeHdfAttribute(headerGroup, "Flag_Metals", baryonic); + writeHdfAttribute(headerGroup, "Flag_Entropy_ICs", 0); writeHdfAttribute(headerGroup, "BoxSize", this->boxLength); writeHdfAttribute(headerGroup, "Omega0", this->cosmology.OmegaM0); writeHdfAttribute(headerGroup, "OmegaLambda", this->cosmology.OmegaLambda0); diff --git a/genetIC/src/io/swift.hpp b/genetIC/src/io/swift.hpp new file mode 100644 index 00000000..34dfad7d --- /dev/null +++ b/genetIC/src/io/swift.hpp @@ -0,0 +1,50 @@ +#ifndef IC_SWIFT_HPP +#define IC_SWIFT_HPP + +#include "gadgethdf.hpp" + +namespace io { + namespace swift { + template + class SwiftHDFOutput : public gadgethdf::GadgetHDFOutput { + public: + SwiftHDFOutput(double Boxlength, + particle::mapper::ParticleMapper &mapper, + particle::SpeciesToGeneratorMap &generators, + const cosmology::CosmologicalParameters> &cosmology, + int nFiles) : + gadgethdf::GadgetHDFOutput(Boxlength, mapper, generators, cosmology, nFiles) {} + + bool forceVariableMass() const override { + return true; + } + + }; + + //! \brief Generates swift output + /*! + \param name - name of output file + \param Boxlength - simulation size in Mpc/h + \param mapper - particle mapper used to link particles to grid locations + \param generators - particles generators for each particle species (vector) + \param cosmology - cosmological parameters + */ + template + void save(const std::string &name, double Boxlength, + particle::mapper::ParticleMapper &mapper, + particle::SpeciesToGeneratorMap &generators, + const cosmology::CosmologicalParameters> &cosmology, + int nFiles) { + + HighFive::SilenceHDF5 silence; // suppresses HDF5 warnings while in scope + SwiftHDFOutput output(Boxlength, mapper, generators, cosmology, nFiles); + output(name); + + } + + } +} + +#endif + + From d97e257aa71718352d4ca553db22368b186ff074 Mon Sep 17 00:00:00 2001 From: Andrew Pontzen Date: Sat, 20 Apr 2024 22:38:53 +0100 Subject: [PATCH 16/17] Bump version to reflect new feature --- genetIC/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/genetIC/src/main.cpp b/genetIC/src/main.cpp index db85b51f..a115c7f6 100644 --- a/genetIC/src/main.cpp +++ b/genetIC/src/main.cpp @@ -170,7 +170,7 @@ void setup_parser(tools::ClassDispatch &dispatch) { } void header(ostream &outf, std::string prefix="") { - outf << prefix << "genetIC v1.4.0, compiled: " << __DATE__ << ", " << __TIME__ << endl; + outf << prefix << "genetIC v1.5.0, compiled: " << __DATE__ << ", " << __TIME__ << endl; time_t now = time(0); struct tm tstruct; char buf[80]; From 6254451e065ea1ab9b6f472f2ca02a10ba15ef56 Mon Sep 17 00:00:00 2001 From: Andrew Pontzen Date: Sun, 21 Apr 2024 09:51:19 +0100 Subject: [PATCH 17/17] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b3485088..0ac56def 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,10 @@ GenetIC GenetIC is a code to generate initial conditions for cosmological simulations, especially for zoom simulations of galaxies. It provides support for 'genetic modifications' as described by e.g. [Roth et al 2015](https://arxiv.org/abs/1504.07250), [Rey & Pontzen 2018](https://arxiv.org/abs/1706.04615). It also supports 'splicing' as described by [Cadiou et al 2021](https://arxiv.org/abs/2107.03407). * The main code is written in C++ and can be found (with build instructions and a test suite) in the subfolder `genetIC`. * The code is also available as [docker](http://docker.io) image `apontzen/genetic` (see the user manual for further information) +* A **hands-on tutorial** for genetic modification can be found at https://github.com/pynbody/genetic_example +* **User documentation** can be found in the form of a PDF manual, also at https://github.com/pynbody/genetIC/releases/latest * A set of python tools for development and testing is provided in `tools`. * If you wish to use the code for science, we recommend adopting a particular (numbered) version. The most recent release can be downloaded at https://github.com/pynbody/genetIC/releases/latest -* Documentation can be found in the form of a PDF user manual, also at https://github.com/pynbody/genetIC/releases/latest * The technical underpinnings of the code are described in a release paper at https://arxiv.org/abs/2006.01841 License and acknowledgement policy