From 9dc36804595578e5148bb867981ceb39d47378e3 Mon Sep 17 00:00:00 2001 From: Roland Haas Date: Mon, 30 Dec 2024 10:51:44 -0500 Subject: [PATCH] CarpetX: introduce AnyTypeScalarRef --- CarpetX/src/driver.cxx | 66 ++++++++++++++++++++++++++++---------- CarpetX/src/driver.hxx | 31 +++++++++++++++--- CarpetX/src/io_openpmd.cxx | 1 + CarpetX/src/io_tsv.cxx | 41 +++-------------------- CarpetX/src/valid.cxx | 2 ++ 5 files changed, 83 insertions(+), 58 deletions(-) diff --git a/CarpetX/src/driver.cxx b/CarpetX/src/driver.cxx index bb85d2821..d8a8debac 100644 --- a/CarpetX/src/driver.cxx +++ b/CarpetX/src/driver.cxx @@ -2289,6 +2289,28 @@ YAML::Emitter &operator<<(YAML::Emitter &yaml, const amrex::AmrCore &amrcore) { } // namespace amrex namespace CarpetX { +std::ostream & +operator<<(std::ostream &os, + const GHExt::GlobalData::AnyTypeVector::AnyTypeScalarRef &scalar) { + const char sep = '\t'; + switch (scalar._vect.type()) { + case CCTK_VARIABLE_REAL: + os << *(CCTK_REAL *)scalar._vect.data_at(scalar._idx); + break; + case CCTK_VARIABLE_INT: + os << *(CCTK_INT *)scalar._vect.data_at(scalar._idx); + break; + case CCTK_VARIABLE_COMPLEX: { + CCTK_COMPLEX value = *(CCTK_COMPLEX *)scalar._vect.data_at(scalar._idx); + os << value.real() << sep << value.imag(); + } break; + default: + assert(0 && "Unexpected variable type"); + break; + } + return os; +} + YAML::Emitter &operator<<(YAML::Emitter &yaml, const GHExt::CommonGroupData &commongroupdata) { yaml << YAML::LocalTag("commongroupdata-1.0.0"); @@ -2316,27 +2338,37 @@ YAML::Emitter &operator<<(YAML::Emitter &yaml, const CCTK_COMPLEX &cval) { return yaml; }; +YAML::Emitter & +operator<<(YAML::Emitter &yaml, + const GHExt::GlobalData::AnyTypeVector::AnyTypeScalarRef + &anytypescalarref) { + switch (anytypescalarref._vect.type()) { + case CCTK_VARIABLE_COMPLEX: + yaml << *(const CCTK_COMPLEX *)anytypescalarref._vect.data_at( + anytypescalarref._idx); + break; + case CCTK_VARIABLE_REAL: + yaml << *(const CCTK_REAL *)anytypescalarref._vect.data_at( + anytypescalarref._idx); + break; + case CCTK_VARIABLE_INT: + yaml << *(const CCTK_INT *)anytypescalarref._vect.data_at( + anytypescalarref._idx); + break; + default: + // missed to implement a type + CCTK_VERROR("Cannot handle type %d", anytypescalarref._vect.type()); + break; + } + return yaml; +} + YAML::Emitter & operator<<(YAML::Emitter &yaml, const GHExt::GlobalData::AnyTypeVector &anytypevector) { yaml << YAML::BeginSeq; - for (size_t i = 0; i < anytypevector.size(); ++i) { - switch (anytypevector.type()) { - case CCTK_VARIABLE_COMPLEX: - yaml << *(const CCTK_COMPLEX *)anytypevector.data_at(i); - break; - case CCTK_VARIABLE_REAL: - yaml << *(const CCTK_REAL *)anytypevector.data_at(i); - break; - case CCTK_VARIABLE_INT: - yaml << *(const CCTK_INT *)anytypevector.data_at(i); - break; - default: - // missed to implement a type - CCTK_VERROR("Cannot handle type %d", anytypevector.type()); - break; - } - } + for (size_t i = 0; i < anytypevector.size(); ++i) + yaml << anytypevector[i]; yaml << YAML::EndSeq; return yaml; } diff --git a/CarpetX/src/driver.hxx b/CarpetX/src/driver.hxx index e003fbd96..def917d48 100644 --- a/CarpetX/src/driver.hxx +++ b/CarpetX/src/driver.hxx @@ -153,12 +153,26 @@ struct GHExt { // all data that exists on all levels class AnyTypeVector { - private: - int _type, _typesize; - size_t _count; - void *_data; public: + // access to a single element of a AnyTypeVector + class AnyTypeScalarRef { + public: + AnyTypeScalarRef() = delete; + AnyTypeScalarRef(const AnyTypeVector &vect_, size_t idx_) + : _vect(vect_), _idx(idx_) {} + + private: + const AnyTypeVector &_vect; + const size_t _idx; + + friend YAML::Emitter & + operator<<(YAML::Emitter &yaml, + const AnyTypeScalarRef &anytypescalarref); + friend std::ostream &operator<<(std::ostream &os, + const AnyTypeScalarRef &scalar); + }; + AnyTypeVector() : _type(-1), _typesize(-1), _count(0), _data(nullptr){}; AnyTypeVector(int type_, size_t count_) : _type(-1), _typesize(-1), _count(0), _data(nullptr) { @@ -246,10 +260,19 @@ struct GHExt { return (char *)_data + i * _typesize; }; + AnyTypeScalarRef operator[](size_t idx) const { + return AnyTypeScalarRef(*this, idx); + } + size_t size() const { return _count; }; friend YAML::Emitter &operator<<(YAML::Emitter &yaml, const AnyTypeVector &anytypevector); + + private: + int _type, _typesize; + size_t _count; + void *_data; }; // For subcycling in time, there really should be one copy of each diff --git a/CarpetX/src/io_openpmd.cxx b/CarpetX/src/io_openpmd.cxx index dad8160c4..46caf0e69 100644 --- a/CarpetX/src/io_openpmd.cxx +++ b/CarpetX/src/io_openpmd.cxx @@ -1198,6 +1198,7 @@ void carpetx_openpmd_t::InputOpenPMD(const cGH *const cctkGH, if (poison_undefined_values) { const size_t typesize = size_t(CCTK_VarTypeSize(cgroup.vartype)); + // TODO: Use AnyTypeScalarRef for this? std::vector poison(typesize); assert(cgroup.vartype == CCTK_VARIABLE_REAL || cgroup.vartype == CCTK_VARIABLE_INT || diff --git a/CarpetX/src/io_tsv.cxx b/CarpetX/src/io_tsv.cxx index 5dc92d296..c5df75da2 100644 --- a/CarpetX/src/io_tsv.cxx +++ b/CarpetX/src/io_tsv.cxx @@ -168,23 +168,9 @@ void WriteTSVScalars(const cGH *restrict cctkGH, const std::string &filename, // Output data file << cctkGH->cctk_iteration << sep << cctkGH->cctk_time; const int tl = 0; + const auto &data = arraygroupdata.data.at(tl); for (int vi = 0; vi < arraygroupdata.numvars; ++vi) - switch (cgroup.vartype) { - case CCTK_VARIABLE_REAL: - file << sep << *(const CCTK_REAL *)arraygroupdata.data.at(tl).data_at(vi); - break; - case CCTK_VARIABLE_INT: - file << sep << *(const CCTK_INT *)arraygroupdata.data.at(tl).data_at(vi); - break; - case CCTK_VARIABLE_COMPLEX: { - CCTK_COMPLEX value = - *(const CCTK_COMPLEX *)arraygroupdata.data.at(tl).data_at(vi); - file << sep << value.real() << sep << value.imag(); - } break; - default: - assert(0 && "Unexpected variable type"); - break; - } + file << sep << data[vi]; file << "\n"; } @@ -243,28 +229,9 @@ void WriteTSVArrays(const cGH *restrict cctkGH, const std::string &filename, for (int dir = 0; dir < arraygroupdata.dimension; ++dir) file << sep << (dir == out_dir ? i : 0); const int tl = 0; + const auto &data = arraygroupdata.data.at(tl); for (int vi = 0; vi < arraygroupdata.numvars; ++vi) - switch (cgroup.vartype) { - case CCTK_VARIABLE_REAL: - file << sep - << *(const CCTK_REAL *)arraygroupdata.data.at(tl).data_at( - np * vi + DI[out_dir] * i); - break; - case CCTK_VARIABLE_INT: - file << sep - << *(const CCTK_INT *)arraygroupdata.data.at(tl).data_at( - np * vi + DI[out_dir] * i); - break; - case CCTK_VARIABLE_COMPLEX: { - CCTK_COMPLEX value = - *(const CCTK_COMPLEX *)arraygroupdata.data.at(tl).data_at( - np * vi + DI[out_dir] * i); - file << sep << value.real() << sep << value.imag(); - } break; - default: - assert(0 && "Unexpected variable type"); - break; - } + file << sep << data[np * vi + DI[out_dir] * i]; file << "\n"; } } diff --git a/CarpetX/src/valid.cxx b/CarpetX/src/valid.cxx index ce15efc79..0352c6bd2 100644 --- a/CarpetX/src/valid.cxx +++ b/CarpetX/src/valid.cxx @@ -236,6 +236,7 @@ void poison_invalid_ga(const int gi, const int vi, const int tl) { int n_elems = 1; for (int i = 0; i < dimension; i++) n_elems *= gsh[i]; + // TODO: use AnyScalarTypeRef for this? assert(group.vartype == CCTK_VARIABLE_COMPLEX || group.vartype == CCTK_VARIABLE_REAL || group.vartype == CCTK_VARIABLE_INT); @@ -506,6 +507,7 @@ void check_valid_ga(const int gi, const int vi, const int tl, int n_elems = 1; for (int i = 0; i < dimension; i++) n_elems *= gsh[i]; + // TODO: use AnyScalarTypeRef for this? switch (group.vartype) { case CCTK_VARIABLE_COMPLEX: { const poison_value_t poison_value;