Line data Source code
1 : #ifndef BL_MFITER_H_ 2 : #define BL_MFITER_H_ 3 : #include <AMReX_Config.H> 4 : 5 : #include <AMReX_FabArrayBase.H> 6 : 7 : #include <memory> 8 : 9 : namespace amrex { 10 : 11 : #ifdef AMREX_USE_GPU 12 : inline bool TilingIfNotGPU () noexcept { return Gpu::notInLaunchRegion(); } 13 : #else 14 732502 : inline constexpr bool TilingIfNotGPU () noexcept { return true; } 15 : #endif 16 : 17 : template<class T> class FabArray; 18 : 19 : struct MFItInfo 20 : { 21 : bool do_tiling{false}; 22 : bool dynamic{false}; 23 : bool device_sync; 24 : int num_streams; 25 : IntVect tilesize; 26 0 : MFItInfo () noexcept 27 0 : : device_sync(!Gpu::inNoSyncRegion()), num_streams(Gpu::numGpuStreams()), 28 0 : tilesize(IntVect::TheZeroVector()) {} 29 0 : MFItInfo& EnableTiling (const IntVect& ts = FabArrayBase::mfiter_tile_size) noexcept { 30 0 : do_tiling = true; 31 0 : tilesize = ts; 32 0 : return *this; 33 : } 34 0 : MFItInfo& SetDynamic (bool f) noexcept { 35 0 : dynamic = f; 36 0 : return *this; 37 : } 38 : MFItInfo& DisableDeviceSync () noexcept { 39 : device_sync = false; 40 : return *this; 41 : } 42 : MFItInfo& SetDeviceSync (bool f) noexcept { 43 : device_sync = f; 44 : return *this; 45 : } 46 : MFItInfo& SetNumStreams (int n) noexcept { 47 : num_streams = n; 48 : return *this; 49 : } 50 : MFItInfo& UseDefaultStream () noexcept { 51 : num_streams = 1; 52 : return *this; 53 : } 54 : }; 55 : 56 : class MFIter 57 : { 58 : public: 59 : //! Flags that specify tiling modes. All these flags are off by default. 60 : enum Flags { 61 : //!Tiling: Enabling the tiling mode 62 : Tiling = 0x01, 63 : /** 64 : * \brief AllBoxes: If on, all threads/workers loop over all boxes without tiling. 65 : * This essentially loops over indexMap. 66 : * Note that many functions won't work with this. 67 : */ 68 : AllBoxes = 0x02, 69 : //! NoTeamBarrier: This option is for Team only. If on, there is no barrier in MFIter dtor. 70 : NoTeamBarrier = 0x04 71 : }; 72 : 73 : /** 74 : * \brief The default constructor does not enable tiling (flags_ is set to 0 by default). 75 : * However, the tiling mode can be enabled by explicitly turning the tiling flag on (i.e. flags_ = Tiling). 76 : * The tile size in this case is defined by FabArrayBase::mfiter_tile_size 77 : */ 78 : explicit MFIter (const FabArrayBase& fabarray, 79 : unsigned char flags_=0); 80 : 81 : //! Enable tiling with the default tile size, which is defined by FabArrayBase::mfiter_tile_size 82 : MFIter (const FabArrayBase& fabarray, 83 : bool do_tiling); 84 : 85 : //! Enable tiling with explicit tile size and flags (See type Flags for more information) 86 : MFIter (const FabArrayBase& fabarray, 87 : const IntVect& tilesize, 88 : unsigned char flags_=0); 89 : 90 : MFIter (const BoxArray& ba, const DistributionMapping& dm, unsigned char flags_=0); 91 : 92 : MFIter (const BoxArray& ba, const DistributionMapping& dm, bool do_tiling); 93 : 94 : MFIter (const BoxArray& ba, const DistributionMapping& dm, 95 : const IntVect& tilesize, unsigned char flags_=0); 96 : 97 : MFIter (const FabArrayBase& fabarray, const MFItInfo& info); 98 : 99 : MFIter (const BoxArray& ba, const DistributionMapping& dm, const MFItInfo& info); 100 : 101 : MFIter (MFIter&& rhs) = default; 102 : MFIter (MFIter const&) = delete; 103 : MFIter& operator= (MFIter const&) = delete; 104 : MFIter& operator= (MFIter &&) = delete; 105 : 106 : // dtor 107 : ~MFIter (); 108 : 109 : //! Return the tile Box at the current index. 110 : [[nodiscard]] Box tilebox () const noexcept; 111 : 112 : //! Return the tilebox with provided nodal flag 113 : [[nodiscard]] Box tilebox (const IntVect& nodal) const noexcept; 114 : 115 : //! Return the tilebox with provided nodal flag and grown cells 116 : [[nodiscard]] Box tilebox (const IntVect& nodal, const IntVect& ngrow) const noexcept; 117 : 118 : //! Return the dir-nodal (or all nodal if dir<0) Box at the current index. 119 : [[nodiscard]] Box nodaltilebox (int dir=-1) const noexcept; 120 : 121 : //! Return the tile box at the current index grown to include ghost cells. 122 : [[nodiscard]] Box growntilebox (int ng=-1000000) const noexcept; 123 : 124 : [[nodiscard]] Box growntilebox (const IntVect& ng) const noexcept; 125 : 126 : //! Return the dir-nodal (or all nodal if dir<0) box grown to include ghost cells. 127 : [[nodiscard]] Box grownnodaltilebox (int dir=-1, int ng=-1000000) const noexcept; 128 : 129 : [[nodiscard]] Box grownnodaltilebox (int dir, const IntVect& ng) const noexcept; 130 : 131 : //! Return the valid Box in which the current tile resides. 132 1419440 : [[nodiscard]] Box validbox () const noexcept { return fabArray->box((*index_map)[currentIndex]); } 133 : 134 : //! Return the Box of the FAB at which we currently point. 135 1163100 : [[nodiscard]] Box fabbox () const noexcept { return fabArray->fabbox((*index_map)[currentIndex]); } 136 : 137 : //! Increment iterator to the next tile we own. 138 : void operator++ () noexcept; 139 : 140 : //! Is the iterator valid i.e. is it associated with a FAB? 141 9908250 : [[nodiscard]] bool isValid () const noexcept { return currentIndex < endIndex; } 142 : 143 : //! The index into the underlying BoxArray of the current FAB. 144 : [[nodiscard]] int index () const noexcept { return (*index_map)[currentIndex]; } 145 : 146 : //! The number of indices. 147 : [[nodiscard]] int length () const noexcept { return (endIndex - beginIndex); } 148 : 149 : //! The current local tile index in the current grid; 150 : [[nodiscard]] int LocalTileIndex () const noexcept {return local_tile_index_map ? (*local_tile_index_map)[currentIndex] : 0;} 151 : 152 : //! The the number of tiles in the current grid; 153 : [[nodiscard]] int numLocalTiles() const noexcept {return num_local_tiles ? (*num_local_tiles)[currentIndex] : 1;} 154 : 155 : /** 156 : * \brief Return local index into the vector of fab pointers, m_fabs_v 157 : * When AllBoxes is on, local_index_map is a nullptr and local index is current index. 158 : */ 159 11858600 : [[nodiscard]] int LocalIndex () const noexcept { return local_index_map ? (*local_index_map)[currentIndex] : currentIndex; } 160 : 161 : //! Constant reference to FabArray over which we're iterating. 162 : [[nodiscard]] const FabArrayBase& theFabArrayBase () const noexcept { return *fabArray; } 163 : 164 : [[nodiscard]] int tileIndex () const noexcept {return currentIndex;} 165 : 166 : [[nodiscard]] const DistributionMapping& DistributionMap () const noexcept { return fabArray->DistributionMap(); } 167 : 168 : static int allowMultipleMFIters (int allow); 169 : 170 : static int currentDepth (); 171 : 172 : void Finalize (); 173 : 174 : protected: 175 : 176 : std::unique_ptr<FabArrayBase> m_fa; //!< This must be the first member! 177 : 178 : const FabArrayBase* fabArray; 179 : 180 : IntVect tile_size; 181 : 182 : unsigned char flags; 183 : int currentIndex; 184 : int beginIndex; 185 : int endIndex; 186 : int streams; 187 : IndexType typ; 188 : 189 : bool dynamic; 190 : bool finalized = false; 191 : 192 : struct DeviceSync { 193 : DeviceSync (bool f) : flag(f) {} 194 : DeviceSync (DeviceSync&& rhs) noexcept : flag(std::exchange(rhs.flag,false)) {} 195 : ~DeviceSync () = default; 196 : DeviceSync (DeviceSync const&) = delete; 197 : DeviceSync& operator= (DeviceSync const&) = delete; 198 : DeviceSync& operator= (DeviceSync &&) = delete; 199 : explicit operator bool() const noexcept { return flag; } 200 : bool flag = true; 201 : }; 202 : DeviceSync device_sync; 203 : 204 : const Vector<int>* index_map; 205 : const Vector<int>* local_index_map; 206 : const Vector<Box>* tile_array; 207 : const Vector<int>* local_tile_index_map; 208 : const Vector<int>* num_local_tiles; 209 : 210 : static AMREX_EXPORT int nextDynamicIndex; 211 : static AMREX_EXPORT int depth; 212 : static AMREX_EXPORT int allow_multiple_mfiters; 213 : 214 : void Initialize (); 215 : }; 216 : 217 : //! Is it safe to have these two MultiFabs in the same MFiter? 218 : //! True means safe; false means maybe. 219 8966 : inline bool isMFIterSafe (const FabArrayBase& x, const FabArrayBase& y) { 220 8966 : return x.DistributionMap() == y.DistributionMap() 221 8966 : && BoxArray::SameRefs(x.boxArray(), y.boxArray()); 222 : } 223 : 224 : } 225 : 226 : #endif