25#ifndef VELOCITY_MESH_GPU_H
26#define VELOCITY_MESH_GPU_H
37#include "include/hashinator/hashinator.h"
38#include "include/splitvector/splitvec.h"
43#if defined(DEBUG_VLASIATOR) || defined(DEBUG_SPATIAL_CELL)
109 bool setGrid(
const std::vector<vmesh::GlobalID>& globalIDs);
110 bool setGrid(
const split::SplitVector<vmesh::GlobalID>& globalIDs);
144 meshID = std::numeric_limits<size_t>::max();
159 if (other.localToGlobalMap.size() > 0) {
160 globalToLocalMap = Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>(other.globalToLocalMap);
161 localToGlobalMap = split::SplitVector<vmesh::GlobalID>(other.localToGlobalMap.capacity());
195 printf(
"VMESH CAPACITY ERROR: LTG capacity %lu vs cached value %lu in %s : %d\n",cap1,
ltg_capacity,__FILE__,__LINE__);
199 printf(
"VMESH CAPACITY ERROR: GTL sizePower %lu vs cached value %lu in %s : %d\n",cap2,
gtl_sizepower,__FILE__,__LINE__);
207 + currentBucketCount *
sizeof(Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>);
212 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
218 printf(
"VMESH CAPACITY ERROR: capacity %lu vs cached value %lu in %s : %d\n",cap1,
ltg_capacity,__FILE__,__LINE__);
227 #if !defined(__CUDA_ARCH__) && !defined(__HIP_DEVICE_COMPILE__)
237 #if !defined(__CUDA_ARCH__) && !defined(__HIP_DEVICE_COMPILE__)
242 printf(
"VMESH CHECK ERROR: capacity %lu vs cached value %lu in %s : %d\n",cap1,
ltg_capacity,__FILE__,__LINE__);
246 printf(
"VMESH CHECK ERROR: sizepower %lu vs cached value %lu in %s : %d\n",cap2,
gtl_sizepower,__FILE__,__LINE__);
250 printf(
"VMESH CHECK ERROR: size %lu vs cached value %lu in %s : %d\n",size1,
ltg_size,__FILE__,__LINE__);
254 if (size1 != size2) {
255 printf(
"VMESH CHECK ERROR: LTG size %lu vs GTL size %lu in %s : %d\n",size1,size2,__FILE__,__LINE__);
260 for (
size_t b=0; b<size1; ++b) {
262 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
272 printf(
"VMESH CHECK ERROR: localToGlobalMap[%lu] = %u but globalToLocalMap[%u] = %u\n",b,globalID,globalID,localID);
278 printf(
"VMESH CHECK ERROR: localToGlobalMap[%lu] = %u but could not find in globalToLocalMap ",b,globalID);
283 printf(
"VMESH CHECK ERROR Encountered %lu failures.\n",fail);
286 #if !defined(__CUDA_ARCH__) && !defined(__HIP_DEVICE_COMPILE__)
294 #if !defined(__CUDA_ARCH__) && !defined(__HIP_DEVICE_COMPILE__)
302 assert(0 &&
"VM check ERROR: sizes differ");
305 printf(
"VM Size: %u \n",thisSize);
308 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
314 printf(
"vmesh LID [%6u] => GID [%6u] => [%6u]\n",b,globalID,localID);
316 #if !defined(__CUDA_ARCH__) && !defined(__HIP_DEVICE_COMPILE__)
339 std::cerr<<
"VMESH CLEAR FAILED"<<std::endl;
348 if (sourceLID !=
size()-1) {
349 assert( 0 &&
"Error! Moving velocity mesh entry from position which is not last LID!");
354 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
368 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
384 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
402 getIndices(globalID,indices[0],indices[1],indices[2]);
463 assert (0 &&
"ERROR invalid local id");
558 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
605 const size_t mySize =
size();
616 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
630 const size_t mySize =
size();
638 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
650 if (position.second ==
true) {
658 return position.second;
663 const size_t blocksSize = blocks.size();
665 printf(
"vmesh: too many blocks, current size is %lu",
ltg_size);
666 printf(
", adding %lu blocks", blocksSize);
680 globalToLocalMap.insertIndex<
false>(_localToGlobalMapData,blocksSize,0.5,stream);
691 size_t newElements = 0;
692 for (
size_t b=0;
b<blocksSize; ++
b) {
710 #if !(defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__))
714 const size_t blocksSize = blocks->size();
716 printf(
"vmesh: too many blocks, current size is %lu",
ltg_size);
717 printf(
", adding %lu blocks", blocksSize);
722 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
724 size_t newElements = 0;
725 for (
size_t b=0; b<blocksSize; ++b) {
748 globalToLocalMap.insertIndex<
false>(_localToGlobalMapData,blocksSize,0.5,stream);
760 size_t newElements = 0;
761 for (
size_t b=0; b<blocksSize; ++b) {
765 if (position.second) {
780#if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
786 if (LID >
size()-1) {
787 printf(
"vmesh replaceBlock error: LID is too large!\n");
795 printf(
"vmesh replaceBlock error: oldGID and oldLID don't match!\n");
805 if (LID >
size()-1) {
806 assert(0 &&
"vmesh placeBlock error: LID is too large!");
810 assert(0 &&
"vmesh placeBlock error: set_element not a new entry!");
822 printf(
"vmesh deleteBlock error: GID is invalidGlobalID! (LID %ul)\n",LID);
825 printf(
"vmesh deleteBlock error: LID is invalidLocalID! (GID %ul)\n",GID);
829 printf(
"vmesh deleteBlock error: GID %ul does not exist! (LID %ul)\n",GID,LID);
831 if (it->second != LID) {
832 printf(
"vmesh deleteBlock error: LID %ul found with GID %ul does not match provided LID %ul!\n",it->second,GID,LID);
836 printf(
"vmesh deleteBlock error: GID %ul found with LID %ul does not match provided GID %ul!\n",
localToGlobalMap.at(LID),LID,GID);
852 const size_t mySize =
size();
873 if (newMapSize != mapSize-1) {
874 printf(
"warpError in VelocityMesh::warpPop: map size %u is not expected %u! (thread %u)\n",newMapSize,(
vmesh::LocalID)(mapSize-1),(
vmesh::LocalID)b_tid);
877 if (newVecSize != mySize-1) {
878 printf(
"warpError in VelocityMesh::warpPop: vector size %u is not expected %u! (thread %u)\n",newVecSize,(
vmesh::LocalID)(mySize-1),(
vmesh::LocalID)b_tid);
894 printf(
"Warp error in VelocityMesh::warpGetLocalID: thread %u search did not find entry, warp search found LID %u for GID %u\n",(
vmesh::LocalID)b_tid,retval,globalID);
896 }
else if (retval != it->second) {
897 printf(
"Warp error in VelocityMesh::warpGetLocalID: LID %u (warp) != %u (thread %u) for GID %u\n",
908 if (sourceLID !=
size()-1) {
909 assert( 0 &&
"Error! Moving velocity mesh entry from position which is not last LID!");
932 if (preMapSize-1 != postMapSize) {
933 printf(
"warpError in VelocityMesh::warpMove: map size %u is not expected %u! (thread %u)\n",postMapSize,preMapSize,(
vmesh::LocalID)b_tid);
936 if (preVecSize-1 != postVecSize) {
937 printf(
"warpError in VelocityMesh::warpMove: vector size %u is not expected %u! (thread %u)\n",postVecSize,preVecSize,(
vmesh::LocalID)b_tid);
940 if (targetLID != postLID) {
941 printf(
"warpError in VelocityMesh::warpMove: Entry at GID %u is %u instead of expected %u! (thread %u)\n",moveGID,postLID,targetLID,(
vmesh::LocalID)b_tid);
944 if (
count(removeGID) != 0) {
946 printf(
"warpError in VelocityMesh::warpMove: Deleted GID %u still found in map with LID %u! (used to be LID %u) (thread %u)\n",removeGID,removedLIDfound,targetLID,(
vmesh::LocalID)b_tid);
962 if (verify != retval) {
963 printf(
"warpError in VelocityMesh::warpCount: Searched GID %u found in map with LID %u for thread %u, but warpFind returned %u!\n",globalID,verify,(
vmesh::LocalID)b_tid,retval);
991 printf(
"Warp error in VelocityMesh::warpFindBlock: single-thread %u search did not find entry, warp search found LID %u for GID %u\n",(
vmesh::LocalID)b_tid,retval,blockGID);
992 }
else if (retval != it->second) {
993 printf(
"Warp error in VelocityMesh::warpFindBlock: LID %u (warp) != %u (thread %u) for GID %u\n",
1006 __shared__
bool inserted;
1022 if (inserted ==
true && b_tid==0) {
1033 if (newMapSize != mapSize+1) {
1034 printf(
"warpError in VelocityMesh::warpPush_back: map size %u is not expected %u! (thread %u)\n",newMapSize,mapSize+1,(
vmesh::LocalID)b_tid);
1037 if (newVecSize != mySize+1) {
1038 printf(
"warpError in VelocityMesh::warpPush_back: vector size %u is not expected %u! (thread %u)\n",newVecSize,mySize+1,(
vmesh::LocalID)b_tid);
1041 if (postLID != mySize) {
1042 printf(
"warpError in VelocityMesh::warpPush_back: hashmap returns LID %u but expected %u! (thread %u)\n",postLID,mySize,(
vmesh::LocalID)b_tid);
1045 if (postLID != mySize) {
1046 printf(
"warpError in VelocityMesh::warpPush_back: vector entry is GID %u but expected %u! (thread %u)\n",postGID,globalID,(
vmesh::LocalID)b_tid);
1059 printf(
"vmesh: too many blocks, current size is %u",mySize);
1060 printf(
", adding %u blocks", blocksSize);
1066 __shared__
bool inserted;
1075 if (inserted ==
true && b_tid == 0) {
1081 if (inserted ==
false) {
1083 printf(
"vmesh: failed to push_back new block! %d of %d\n",(uint)(nInserted+1),(uint)blocksSize);
1099 const size_t b_tid) {
1103 if (LID >
size()-1) {
1104 printf(
"vmesh replaceBlock error: LID %u is too large for size %u!\n",LID,(
vmesh::LocalID)
size());
1114 printf(
"Warp error in VelocityMesh::warpReplaceBlock: thread %u search did not find entry, warp search found LID %u for GID %u\n",(
vmesh::LocalID)b_tid,LIDold,GIDold);
1117 }
else if (LIDold != it->second) {
1118 printf(
"Warp error in VelocityMesh::warpReplaceBlock: LID %u (warp) != %u (thread %u) for GID %u\n",
1124 printf(
"vmesh replaceBlock error: oldGID and oldLID don't match!\n");
1142 printf(
"Warp error in VelocityMesh::warpReplaceBlock: warp-erased GID %u LID %u but thread %u still finds LID %u associated with it!\n",GIDold,LID,(
vmesh::LocalID)b_tid,it2->second);
1145 bool newlyadded =
false;
1163 printf(
"Warp error in VelocityMesh::warpReplaceBlock: warp-inserted GID %u LID %u but thread %u cannot find it!\n",GIDnew,LID,(
vmesh::LocalID)b_tid);
1166 printf(
"warpAccessor reported true for insertion!\n");
1168 printf(
"warpAccessor reported false for insertion!\n");
1174 }
else if (it3->second != LID) {
1175 printf(
"Warp error in VelocityMesh::warpReplaceBlock: warp-inserted GID %u LID %u but thread %u instead finds LID %u!\n",GIDnew,LID,(
vmesh::LocalID)b_tid,it3->second);
1197 if (LID >
size()-1) printf(
"vmesh placeBlock error: LID is too large!\n");
1203 printf(
"Warp error in VelocityMesh::warpPlaceBlock: single-thread %u search found GID %u=%u LID %u before it was inserted!\n",(
vmesh::LocalID)b_tid,GID,it->first,it->second);
1214 bool newlyadded =
false;
1219 printf(
"warpPlaceBlock error GID %u LID %u reported as not newly added! Size %zu.\n",GID,LID,
localToGlobalMap.size());
1222 assert(newlyadded &&
"newlyAdded warpPlaceBlock");
1231 printf(
"Warp error in VelocityMesh::warpPlaceBlock: single-thread %u search did not find inserted GID %u LID %u\n",(
vmesh::LocalID)b_tid,GID,LID);
1236 }
else if (LID != it->second) {
1237 printf(
"Warp error in VelocityMesh::warpPlaceBlock: LID %u (warp) != %u (thread %u) for GID %u\n",LID,it->second,(
vmesh::LocalID)b_tid,GID);
1251 printf(
"vmesh warpDeleteBlock error: GID is invalidGlobalID! (LID %ul)\n",LID);
1254 printf(
"vmesh warpDeleteBlock error: LID is invalidLocalID! (GID %ul)\n",GID);
1262 printf(
"vmesh warpDeleteBlock error: GID %ul does not exist! (LID %ul)\n",GID,LID);
1264 if (retval != LID) {
1265 printf(
"vmesh warpDeleteBlock error: LID %ul warpFound with GID %ul does not match provided LID %ul!\n",
1270 printf(
"vmesh warpDeleteBlock error: GID %ul warpFound with LID %ul does not match provided GID %ul!\n",
1292 printf(
"Warp error in VelocityMesh::warpDeleteBlock: GID %u still found with LID %u for thread %u!\n",GID,it->second,(
vmesh::LocalID)b_tid);
1316 printf(
"Warning! Slow version of VelocityMesh::setGrid.\n");
1331 printf(
"Warning! Slow version of VelocityMesh::setGrid.\n");
1368 assert(newSize <= currentCapacity &&
"insufficient vector capacity in vmesh::device_setNewSize");
1370 assert(ceil(log2(newSize)) <= currentSizePower &&
"insufficient map capacity in vmesh::device_setNewSize");
1392 uint HashmapReqSize = (uint)ceil(log2(newCapacity)) +1;
1410 #if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
1416 printf(
"VMESH SIZE ERROR: size %lu vs cached value %lu in %s : %d\n",size1,
ltg_size,__FILE__,__LINE__);
1428 printf(
"VMESH SIZE ERROR: LTG size %lu vs cached value %lu in %s : %d\n",size1,
ltg_size,__FILE__,__LINE__);
1431 printf(
"VMESH SIZE ERROR: GTL size %lu vs cached value %lu in %s : %d\n",size1,
ltg_size,__FILE__,__LINE__);
1435 +
ltg_size *
sizeof(Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>);
1475 phiprof::Timer cleanupTimer {
"Hashinator tombstones"};
1479 cleanupTimer.stop();
1494 printf(
"GPU localToGlobalMap size %lu capacity %lu cached size %lu cached capacity %lu\nGPU globalToLocalMap fill %lu sizePower %lu cached sizePower %lu\n",
#define gpuStreamSynchronize
#define gpuDeviceSynchronize
size_t count(const GID &key) const
ARCH_DEV size_t warpCount(const vmesh::GlobalID globalID, const size_t b_tid) const
void setNewCapacity(const vmesh::LocalID &newCapacity)
ARCH_HOSTDEV void getIndicesZ(const vmesh::GlobalID globalID, vmesh::LocalID &k) const
ARCH_HOSTDEV size_t capacity() const
void gpu_cleanHashMap(gpuStream_t stream)
ARCH_HOSTDEV const vmesh::LocalID * getGridLength() const
bool push_back(const vmesh::GlobalID &globalID)
ARCH_HOSTDEV Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > * gpu_expose_map()
void setNewCachedSize(const vmesh::LocalID newSize)
bool setGrid(const std::vector< vmesh::GlobalID > &globalIDs)
const VelocityMesh & operator=(const VelocityMesh &other)
OpenBucketHashtable< vmesh::GlobalID, vmesh::LocalID > globalToLocalMap
ARCH_DEV void placeBlock(const vmesh::GlobalID GID, const vmesh::LocalID LID)
ARCH_DEV bool warpMove(const vmesh::LocalID sourceLocalID, const vmesh::LocalID targetLocalID, const size_t b_tid)
static vmesh::LocalID invalidBlockIndex()
ARCH_DEV bool warpPush_back(const vmesh::GlobalID globalID, const size_t b_tid)
ARCH_HOSTDEV vmesh::GlobalID getGlobalID(const Real *coords) const
ARCH_HOSTDEV size_t size() const
bool getBlockCoordinates(const vmesh::GlobalID &globalID, Real coords[3]) const
ARCH_HOSTDEV split::SplitVector< vmesh::GlobalID > * getGrid()
ARCH_DEV void warpPop(const size_t b_tid)
ARCH_DEV vmesh::LocalID warpPush_back(const split::SplitVector< vmesh::GlobalID > &blocks, const size_t b_tid)
static ARCH_HOSTDEV vmesh::GlobalID invalidGlobalID()
vmesh::LocalID push_back(const std::vector< vmesh::GlobalID > &blocks)
static vmesh::LocalID invalidLocalID()
ARCH_HOSTDEV const Real * getMeshMaxLimits() const
ARCH_DEV void device_setNewSize(const vmesh::LocalID newSize)
bool move(const vmesh::LocalID &sourceLocalID, const vmesh::LocalID &targetLocalID)
ARCH_HOSTDEV const Real * getBlockSize() const
bool setMesh(const size_t &meshID)
void setNewSize(const vmesh::LocalID &newSize)
size_t count(const vmesh::GlobalID &globalID) const
ARCH_HOSTDEV const Real * getMeshMinLimits() const
ARCH_HOSTDEV void print()
vmesh::LocalID getLocalID(const vmesh::GlobalID &globalID) const
ARCH_HOSTDEV vmesh::GlobalID getGlobalID(const vmesh::LocalID indices[3]) const
ARCH_DEV void deleteBlock(const vmesh::GlobalID GID, const vmesh::LocalID LID)
void clear(bool shrink=false)
ARCH_HOSTDEV vmesh::GlobalID findBlock(vmesh::GlobalID cellIndices[3]) const
ARCH_DEV void warpDeleteBlock(const vmesh::GlobalID GID, const vmesh::LocalID LID, const size_t b_tid)
void updateCachedCapacity()
ARCH_HOSTDEV size_t sizeInBytes() const
ARCH_DEV vmesh::GlobalID warpFindBlock(vmesh::GlobalID cellIndices[3], const size_t b_tid) const
VelocityMesh(const VelocityMesh &other)
ARCH_HOSTDEV void getIndicesX(const vmesh::GlobalID globalID, vmesh::LocalID &i) const
ARCH_DEV void replaceBlock(const vmesh::GlobalID GIDold, const vmesh::LocalID LID, const vmesh::GlobalID GIDnew)
ARCH_HOSTDEV const Real * getCellSize() const
ARCH_DEV void warpReplaceBlock(const vmesh::GlobalID GIDold, const vmesh::LocalID LID, const vmesh::GlobalID GIDnew, const size_t b_tid)
void gpu_prefetchDevice(gpuStream_t stream)
ARCH_HOSTDEV bool isInitialized() const
std::vector< vmesh::GlobalID > localToGlobalMap
vmesh::GlobalID getGlobalID(const vmesh::LocalID &localID) const
ARCH_DEV void warpPlaceBlock(const vmesh::GlobalID GID, const vmesh::LocalID LID, const size_t b_tid)
static vmesh::GlobalID invalidGlobalID()
size_t size(bool dummy=0) const
bool initialize(const size_t &meshID)
static ARCH_HOSTDEV vmesh::LocalID invalidBlockIndex()
void gpu_prefetchHost(gpuStream_t stream)
void getIndices(const vmesh::GlobalID &globalID, vmesh::LocalID &i, vmesh::LocalID &j, vmesh::LocalID &k) const
static ARCH_HOSTDEV vmesh::LocalID invalidLocalID()
size_t capacityInBytes() const
ARCH_HOSTDEV size_t getMesh() const
void getBlockInfo(const vmesh::GlobalID &globalID, Real *array) const
ARCH_DEV vmesh::LocalID warpGetLocalID(const vmesh::GlobalID globalID, const size_t b_tid) const
ARCH_HOSTDEV void getIndicesY(const vmesh::GlobalID globalID, vmesh::LocalID &j) const
__host__ gpuStream_t gpu_getStream()
static const uint INIT_MAP_SIZE(16 - WID)
static const uint INIT_VMESH_SIZE(32768/WID3)
static const double BLOCK_ALLOCATION_FACTOR
static const LocalID INVALID_LOCALID
static const GlobalID INVALID_GLOBALID
ARCH_HOSTDEV MeshWrapper * getMeshWrapper()
static const LocalID INVALID_VEL_BLOCK_INDEX
std::array< vmesh::MeshParameters, MAX_VMESH_PARAMETERS_COUNT > * velocityMeshes
static ARCH_HOSTDEV VecSimple< T > floor(VecSimple< T > const &a)