USPPNUMNL5HU5WEOIWJMIFAX6TBZERVAV67XJUJQ6KSNLG55JAGQC FS7Q6TUHBK5WSRDC3TM6KV2BPGWATRBLDHFGEJ72BR3FRDEOC3WAC X7A7HYGU2NPWCZCG5SYFD4NINYDP6UYWFFE3WP6YNLSDIABG2KJAC IV3MLV677VWS7GLESBQZ4HRFNW5TBFBIGIBWXTCHAER3FQ7VG3GQC BSMJ4V7GV3EOGY4KCSTOJQUOFE2OOCIKQETE4WC2WRNLWBQIBW3QC BVR7DVINVPQG7PA6Z7QYVYNQ43YZL7XCC6AOMSMWMGAAB2Q43STAC YIQN7NJTGEVKW7JZHL6CTH6EPCIXCNBYNURIGXPYZAOUX3VAJQMAC 2DKSL6DKZAIYQUJGDULORCKU5K4Z5Z3W4RIKQYDSLKMCNQNDZFBAC KG47IF4CPCUT3BHS34WDRHTH5HYMBTY4OSTB3X7APR2E5ZJ32IYQC W4XMGPEHBCV6AAPJBI4SSEMCDB6KKCGRUC2X2F5YLBY22OR3ICPAC KCIWCVZOHG44WBOLKI2XK33WPHPRI5FWCETF4AOGTPZISKCW3CLQC BPRNUTY7MHK7LK4EY5MY5OFFG3ABOL7LWXD574L35M74YSQPULFAC GQVQJCNQNO2KD7ZMC7RESCUAMUAP7OED6CTA6SYLZKQGXKXZ6T3QC LSOYKV2LJ6WOBTNCW43WXV47RIQEBNZFEJJZM5QA7XDZF4D2PANQC UTHNLH3J3VG7BBJPOKGE6DY7Z2QHDLY72TR2VMEDQYP73SIWZGKAC BJDGFYBMECTJG7BHLNHLSCUCBVYHAY6OGY37FIJP6JDGNDXQNQVAC struct tiletag_t {int level;Box tilebox;int gi, vi, tl;tiletag_t() = delete;friend bool operator==(const tiletag_t &x, const tiletag_t &y) {return make_tuple(x.level, x.tilebox, x.gi, x.vi, x.tl) ==make_tuple(y.level, y.tilebox, y.gi, y.vi, y.tl);}friend bool operator<(const tiletag_t &x, const tiletag_t &y) {return make_tuple(x.level, x.tilebox, x.gi, x.vi, x.tl) <make_tuple(y.level, y.tilebox, y.gi, y.vi, y.tl);}friend ostream &operator<<(ostream &os, const tiletag_t &x) {return os << "tiletag_t{"<< "level:" << x.level << ","<< "tilebox:" << x.tilebox << ","<< "gi:" << x.gi << ","<< "vi:" << x.vi << ","<< "tl:" << x.tl << "}";}operator string() const {ostringstream buf;buf << *this;return buf.str();}};struct checksum_t {valid_t where;uLong crc;checksum_t() = default;inline checksum_t(const valid_t &where): where(where), crc(crc32_z(0, nullptr, 0)) {}template <typename T> inline void add(const T &x) {crc =crc32_z(crc, static_cast<const Bytef *>(static_cast<const void *>(&x)),sizeof x);}friend bool operator==(const checksum_t &x, const checksum_t &y) {return x.where == y.where && x.crc == y.crc;}friend bool operator!=(const checksum_t &x, const checksum_t &y) {return !(x == y);}
friend ostream &operator<<(ostream &os, const checksum_t &x) {return os << "checksum_t{where:" << x.where << ",crc:0x" << hex<< setfill('0') << setw(8) << x.crc << "}";}operator string() const {ostringstream buf;buf << *this;return buf.str();}};typedef map<tiletag_t, checksum_t> checksums_t;checksums_tcalculate_checksums(const vector<vector<vector<valid_t> > > &will_write,const int min_level, const int max_level) {DECLARE_CCTK_PARAMETERS;checksums_t checksums;if (!poison_undefined_values)return checksums;for (int level = min_level; level < max_level; ++level) {auto &restrict leveldata = ghext->leveldata.at(level);auto mfitinfo = MFItInfo().SetDynamic(true).EnableTiling({max_tile_size_x, max_tile_size_y, max_tile_size_z});#pragma omp parallelfor (MFIter mfi(*leveldata.mfab0, mfitinfo); mfi.isValid(); ++mfi) {for (const auto &groupdataptr : leveldata.groupdata) {auto &restrict groupdata = *groupdataptr;const GridPtrDesc1 grid(leveldata, groupdata, mfi);for (int vi = 0; vi < groupdata.numvars; ++vi) {for (int tl = 0; tl < int(groupdata.valid.size()); ++tl) {const tiletag_t tiletag{level, mfi.tilebox(), groupdata.groupindex,vi, tl};const auto &valid = groupdata.valid.at(tl).at(vi);const auto &wr = will_write.at(groupdata.groupindex).at(vi).at(tl);valid_t to_check = valid & ~wr;// Check only those variables which are valid, and where// some part (but not everything) is writtenif (!(wr.any() && to_check.any()))continue;const Array4<const CCTK_REAL> &vars =groupdata.mfab.at(tl)->array(mfi);const GF3D1<const CCTK_REAL> var_ = grid.gf3d(vars, vi);checksum_t checksum(to_check);checksum.add(tiletag);const auto add_point{[&](const Loop::PointDesc &p) { checksum.add(var_(p.I)); }};if (to_check.valid_int)grid.loop_idx(where_t::interior, groupdata.indextype,groupdata.nghostzones, add_point);if (to_check.valid_outer)grid.loop_idx(where_t::boundary, groupdata.indextype,groupdata.nghostzones, add_point);if (to_check.valid_ghosts)grid.loop_idx(where_t::ghosts, groupdata.indextype,groupdata.nghostzones, add_point);#pragma omp criticalchecksums[tiletag] = checksum;}}}}}return checksums;}void check_checksums(const checksums_t checksums, const int min_level,const int max_level) {DECLARE_CCTK_PARAMETERS;if (!poison_undefined_values)return;if (checksums.empty())return;for (int level = min_level; level < max_level; ++level) {auto &restrict leveldata = ghext->leveldata.at(level);auto mfitinfo = MFItInfo().SetDynamic(true).EnableTiling({max_tile_size_x, max_tile_size_y, max_tile_size_z});#pragma omp parallelfor (MFIter mfi(*leveldata.mfab0, mfitinfo); mfi.isValid(); ++mfi) {for (const auto &groupdataptr : leveldata.groupdata) {auto &restrict groupdata = *groupdataptr;const GridPtrDesc1 grid(leveldata, groupdata, mfi);for (int vi = 0; vi < groupdata.numvars; ++vi) {for (int tl = 0; tl < int(groupdata.valid.size()); ++tl) {const tiletag_t tiletag{level, mfi.tilebox(), groupdata.groupindex,vi, tl};if (!checksums.count(tiletag))continue;const auto &old_checksum = checksums.at(tiletag);const auto &did_check = old_checksum.where;assert(did_check.any());const Array4<const CCTK_REAL> &vars =groupdata.mfab.at(tl)->array(mfi);const GF3D1<const CCTK_REAL> var_ = grid.gf3d(vars, vi);checksum_t checksum(did_check);checksum.add(tiletag);const auto add_point{[&](const Loop::PointDesc &p) { checksum.add(var_(p.I)); }};if (did_check.valid_int)grid.loop_idx(where_t::interior, groupdata.indextype,groupdata.nghostzones, add_point);if (did_check.valid_outer)grid.loop_idx(where_t::boundary, groupdata.indextype,groupdata.nghostzones, add_point);if (did_check.valid_ghosts)grid.loop_idx(where_t::ghosts, groupdata.indextype,groupdata.nghostzones, add_point);if (checksum != old_checksum)CCTK_VERROR("Checksum mismatch: variable %s, tile %s, old checksum %s, ""new checksum %s",CCTK_FullVarName(groupdata.firstvarindex + tiletag.vi),string(tiletag).c_str(), string(old_checksum).c_str(),string(checksum).c_str());}}}}}}
CCTK_VERROR("Found invalid input data: iteration %d %s: %s::%s, level %d, ""variable %s%s: need %s, have %s",cctkGH->cctk_iteration, attribute->where, attribute->thorn,attribute->routine, leveldata.level,CCTK_FullVarName(groupdata.firstvarindex + rd.vi),string("_p", rd.tl).c_str(), string(need).c_str(),string(have).c_str());
CCTK_VERROR("Found invalid input data: iteration %d %s: %s::%s, ""level %d, ""variable %s%s: need %s, have %s",cctkGH->cctk_iteration, attribute->where,attribute->thorn, attribute->routine, leveldata.level,CCTK_FullVarName(groupdata.firstvarindex + rd.vi),string("_p", rd.tl).c_str(), string(need).c_str(),string(have).c_str());
uLong crc = crc32_z(0, nullptr, 0);for (int level = min_level; level < max_level; ++level) {auto &restrict leveldata = ghext->leveldata.at(level);auto mfitinfo = MFItInfo().SetDynamic(true).EnableTiling({max_tile_size_x, max_tile_size_y, max_tile_size_z});for (MFIter mfi(*leveldata.mfab0, mfitinfo); mfi.isValid(); ++mfi) {for (const auto &groupdataptr : leveldata.groupdata) {auto &restrict groupdata = *groupdataptr;const GridPtrDesc1 grid(leveldata, groupdata, mfi);for (int vi = 0; vi < groupdata.numvars; ++vi) {for (int tl = 0; tl < int(groupdata.valid.size()); ++tl) {const auto &gf = gfs.at(groupdata.groupindex).at(vi).at(tl);// Check only those variables where some part is writtenif (gf.any()) {const Array4<const CCTK_REAL> &vars =groupdata.mfab.at(tl)->array(mfi);const GF3D1<const CCTK_REAL> var_ = grid.gf3d(vars, vi);const auto addcrc{[&](const Loop::PointDesc &p) {crc = crc32_z(crc,static_cast<const Bytef *>(static_cast<const void *>(&var_(p.I))),sizeof var_(p.I));}};if (!gf.valid_int)grid.loop_idx(where_t::interior, groupdata.indextype,groupdata.nghostzones, addcrc);if (!gf.valid_outer)grid.loop_idx(where_t::boundary, groupdata.indextype,groupdata.nghostzones, addcrc);if (!gf.valid_ghosts)grid.loop_idx(where_t::ghosts, groupdata.indextype,groupdata.nghostzones, addcrc);}}}}}}CCTK_VINFO("CRC-32: 0x%08lx", (unsigned long)crc);
checksums = calculate_checksums(gfs, min_level, max_level);