T35FSMI7CA2CFZSRLTCZQBT2KDSEPDZD5UAPNNGR4YYAJ67LT4PAC
TUDUMVD5MTJJJGVYVOCALOOKOUYNB7LOFJRCYCZDVGN536JAO2OQC
M4Z75FVGV5XY2N3JHOSZZZ33VORN3WASHPP6X4IY43YNEIPFOC3QC
BJDGFYBMECTJG7BHLNHLSCUCBVYHAY6OGY37FIJP6JDGNDXQNQVAC
BVR7DVINVPQG7PA6Z7QYVYNQ43YZL7XCC6AOMSMWMGAAB2Q43STAC
FEMASUBNU32NSG4DNXZX54CGCA57PVRGYO46L3A6F2EJ4BCSJ3SAC
IUYUWJZ3KF2ZNIZREWYZO6DX4SRBLTXJ4ZL4L44H5RES6ZCQ6FFAC
FS7Q6TUHBK5WSRDC3TM6KV2BPGWATRBLDHFGEJ72BR3FRDEOC3WAC
UZAKARMGORRQG733ZUPJOEGL5FG243I32NCC2SRSFDCZKUQ5A52QC
2DD222JSYRPHTXKSRXLSOMSCQPZUORNFLLO2P3GMIDELAAMD5MEQC
WASO7G5FJXRXWNH2U2FLUNEKU6VE63OI3HUYP64BVD4LMD6KE7OQC
PQB3EKQ6MBCXPTW4HB7SGMSTOTYMB3EFZX2573OFCQI6PSOEKCSQC
IVHURSHY4636OGIF3PNDO5CWOVRLJ75M4LP65J6I2E6KAM4QKF4AC
MSBBCXVGD3GRLE5KAI6BKAFRV7SQUWI2SNN43AJAUD3ISRCEXY6QC
BPRNUTY7MHK7LK4EY5MY5OFFG3ABOL7LWXD574L35M74YSQPULFAC
YIQN7NJTGEVKW7JZHL6CTH6EPCIXCNBYNURIGXPYZAOUX3VAJQMAC
2XYZZL42IEZHGDJA6NDKGSQKGJP24LOTLFJ6RNHOKWHHSUYIHGKQC
2DKSL6DKZAIYQUJGDULORCKU5K4Z5Z3W4RIKQYDSLKMCNQNDZFBAC
const Box &fbx = mfi.fabbox(); // allocated array
const Box &vbx = mfi.validbox(); // interior region (without ghosts)
// const Box &bx = mfi.tilebox(); // current region (without ghosts)
const Box &gbx = mfi.growntilebox(); // current region (with ghosts)
const Box &fbx = mfp.fabbox(); // allocated array
const Box &vbx = mfp.validbox(); // interior region (without ghosts)
const Box &gbx = mfp.growntilebox(); // current region (with ghosts)
GridPtrDesc::GridPtrDesc(const GHExt::LevelData &leveldata, const MFIter &mfi)
: GridDesc(leveldata, mfi) {
const Box &fbx = mfi.fabbox(); // allocated array
GridPtrDesc::GridPtrDesc(const GHExt::LevelData &leveldata,
const MFPointer &mfp)
: GridDesc(leveldata, mfp) {
const Box &fbx = mfp.fabbox(); // allocated array
const MFIter &mfi)
: GridDesc(leveldata, mfi) {
const Box &fbx = mfi.fabbox(); // allocated array
const MFPointer &mfp)
: GridDesc(leveldata, mfp) {
const Box &fbx = mfp.fabbox(); // allocated array
thread_info.mfiter = &mfi;
enter_local_mode(threadGH, thread_tilebox, leveldata, mfi);
cout << "level=" << level << " mfi.currentIndex=" << mfi.tileIndex()
<< " mfi.length=" << mfi.length() << "\n";
MFPointer mfp(mfi);
thread_info.mfpointer = &mfp;
enter_local_mode(threadGH, thread_tilebox, leveldata, mfp);
#else
vector<std::function<void()> > tasks;
for (int level = min_level; level < max_level; ++level) {
const auto &restrict leveldata = ghext->leveldata.at(level);
const auto mfitinfo = MFItInfo().EnableTiling(
{max_tile_size_x, max_tile_size_y, max_tile_size_z});
// Note: The MFIter uses global variables and OpenMP barriers
for (MFIter mfi(*leveldata.mfab0, mfitinfo); mfi.isValid(); ++mfi) {
const MFPointer mfp(mfi);
assert(leveldata.mfab0->array(mfi).dataPtr() ==
leveldata.mfab0->array(mfp.index()).dataPtr());
const auto task{[level, mfp, function, attribute] {
const int thread_num = omp_get_thread_num();
thread_local_info_t &restrict thread_info =
*thread_local_info.at(thread_num);
cGH *restrict const threadGH = &thread_info.cctkGH;
TileBox &restrict thread_tilebox = thread_info.tilebox;
const auto &restrict leveldata = ghext->leveldata.at(level);
thread_info.mfpointer = &mfp;
enter_level_mode(threadGH, leveldata);
enter_local_mode(threadGH, thread_tilebox, leveldata, mfp);
CCTK_CallFunction(function, attribute, threadGH);
leave_local_mode(threadGH, thread_tilebox, leveldata, mfp);
leave_level_mode(threadGH, leveldata);
thread_info.mfpointer = nullptr;
}};
tasks.push_back(task);
}
}
#pragma omp parallel
{
// Initialize thread-local state variables
const int thread_num = omp_get_thread_num();
thread_local_info_t &restrict thread_info =
*thread_local_info.at(thread_num);
cGH *restrict const threadGH = &thread_info.cctkGH;
update_cctkGH(threadGH, cctkGH);
// run all tasks
#pragma omp for schedule(dynamic)
for (size_t i = 0; i < tasks.size(); ++i)
tasks[i]();
}
#endif
// Like an MFIter, but does not support iteration, instead it can be copied
struct MFPointer {
int m_index;
Box m_fabbox;
Box m_growntilebox;
Box m_validbox;
IntVect m_nGrowVect;
MFPointer() = delete;
MFPointer(const MFPointer &) = default;
MFPointer(MFPointer &&) = default;
MFPointer &operator=(const MFPointer &) = default;
MFPointer &operator=(MFPointer &&) = default;
MFPointer(const MFIter &mfi)
: m_index(mfi.index()), m_fabbox(mfi.fabbox()),
m_growntilebox(mfi.growntilebox()), m_validbox(mfi.validbox()),
m_nGrowVect(mfi.theFabArrayBase().nGrowVect()) {}
constexpr int index() const noexcept { return m_index; }
constexpr Box fabbox() const noexcept { return m_fabbox; }
constexpr Box growntilebox() const noexcept { return m_growntilebox; }
constexpr Box validbox() const noexcept { return m_validbox; }
constexpr IntVect nGrowVect() const noexcept { return m_nGrowVect; }
};