23#ifndef VLASIATOR_BLOCK_ADJUST_KERNELS_HPP
24#define VLASIATOR_BLOCK_ADJUST_KERNELS_HPP
26#ifdef USE_WARPACCESSORS
27 #define USE_BATCH_WARPACCESSORS
32#define WARPS_PER_MP 64
33#define FULLBLOCKS_PER_MP THREADS_PER_MP/Hashinator::defaults::MAX_BLOCKSIZE
34#define WID3S_PER_MP (2048/WID3)
36#ifdef __HIP_PLATFORM_HCC___
38#define FULLBLOCKS_PER_MP 1
46 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* *
allMaps,
47 const Real* __restrict__ velocity_block_min_values,
48 const bool gatherMass,
53 const int blockiStart = blockIdx.x;
55 const uint
ti = threadIdx.x;
59 const Real velocity_block_min_value = velocity_block_min_values[
cellIndex];
60 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* vbwcl_map =
allMaps[2*
cellIndex];
61 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* vbwncl_map =
allMaps[2*
cellIndex+1];
63 #define warpsPerBlockBatchContent WID3/GPUTHREADS
67 const uint nBlocks =
vmesh->size();
68 #ifdef DEBUG_SPATIAL_CELL
69 if (nBlocks != blockContainer->size()) {
71 printf(
"VBC and vmesh size mismatch in batch_update_velocity_block_content_lists_kernel!\n");
76 const uint blockLID = blockiStart;
78 if (blockLID >= nBlocks) {
82 const Realf* __restrict__ avgs = blockContainer->getData(blockLID);
85 #ifdef DEBUG_SPATIAL_CELL
86 if (blockGID ==
vmesh->invalidGlobalID()) {
88 printf(
"Invalid GID encountered in batch_update_velocity_block_content_lists_kernel!\n");
92 if (blockLID ==
vmesh->invalidLocalID()) {
94 printf(
"Invalid LID encountered in batch_update_velocity_block_content_lists_kernel!\n");
100 bool hasContentThread = (avgs[
ti] >= velocity_block_min_value);
103 gathered_mass[
ti] = avgs[
ti];
106 for (
unsigned int s=
WID3/2; s>0; s>>=1) {
108 gathered_mass[
ti] += gathered_mass[
ti + s];
118 hasContentThread =
gpuKernelAny(0xFFFFFFFF, hasContentThread);
121 if (indexInsideWarp == 0) {
122 has_content[warpIndex] = hasContentThread;
126 if (warpIndex == 0) {
128 hasContentThread =
gpuKernelAny(0xFFFFFFFF, hasContentThread);
132 #ifdef USE_BATCH_WARPACCESSORS
136 has_content[0] = hasContentThread;
139 if (hasContentThread) {
140 vbwcl_map->warpInsert(blockGID,blockLID,
ti);
142 vbwncl_map->warpInsert(blockGID,blockLID,
ti);
148 if (hasContentThread) {
149 vbwcl_map->set_element(blockGID,blockLID);
151 vbwncl_map->set_element(blockGID,blockLID);
156 if (gatherMass && (
ti == 0)) {
157 Real old = atomicAdd(&dev_mass[
cellIndex], gathered_mass[0]);
165__global__
void __launch_bounds__(Hashinator::defaults::MAX_BLOCKSIZE, FULLBLOCKS_PER_MP) batch_reset_all_to_empty(
166 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>**maps
169 const size_t hashmapIndex = blockIdx.y * 2 + blockIdx.z;
170 const size_t tid = threadIdx.x + blockIdx.x * blockDim.x;
171 const size_t stride = gridDim.x * blockDim.x;
172 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* thisMap = maps[hashmapIndex];
173 const size_t len = thisMap->bucket_count();
175 Hashinator::hash_pair<vmesh::GlobalID, vmesh::LocalID>* dst = thisMap->expose_bucketdata<
false>();
177 for (
size_t bucketIndex = tid; bucketIndex < len; bucketIndex += stride) {
178 dst[bucketIndex].first = emptybucket;
183 Hashinator::Info *info = thisMap->expose_mapinfo<
false>();
193__global__
void __launch_bounds__(Hashinator::defaults::MAX_BLOCKSIZE, FULLBLOCKS_PER_MP) check_vector_capacities(
194 const Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* __restrict__
const *maps,
195 const split::SplitVector<vmesh::GlobalID>* __restrict__
const *vecs,
198 const size_t index = threadIdx.x + blockIdx.x * blockDim.x;
199 const Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* __restrict__ thisMap = maps[2*
index];
200 const split::SplitVector<vmesh::GlobalID>* __restrict__ thisVec = vecs[
index];
201 const size_t mapSize = thisMap->size();
202 if (mapSize > thisVec->capacity()) {
203 required_capacities[
index] = mapSize;
211template <
typename Rule,
typename ELEMENT,
bool FIRSTONLY=false>
212__global__
void __launch_bounds__(Hashinator::defaults::MAX_BLOCKSIZE, FULLBLOCKS_PER_MP) extract_GIDs_kernel(
213 const Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* __restrict__
const *input_maps,
214 split::SplitVector<ELEMENT> **output_vecs,
218 const Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* __restrict__
const *rule_maps,
219 const split::SplitVector<vmesh::GlobalID>* __restrict__
const *rule_vectors
223 const size_t hashmapIndex = 2*blockIdx.x;
224 if (input_maps[hashmapIndex]==0) {
227 const Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* __restrict__ thisMap = input_maps[hashmapIndex];
228 split::SplitVector<ELEMENT> *outputVec = output_vecs[
cellIndex];
232 + rule_vectors[
cellIndex]->size() - rule_maps[hashmapIndex]->size();
238 __shared__ uint32_t warpSums[WARPLENGTH];
239 __shared__ uint32_t outputCount;
240 const int tid = threadIdx.x;
241 const int wid = tid / WARPLENGTH;
242 const int w_tid = tid % WARPLENGTH;
244 const size_t warpsPerBlock = blockDim.x / WARPLENGTH;
251 int64_t remaining = thisMap->bucket_count();
252 const uint capacity = outputVec->capacity();
253 uint32_t outputSize = 0;
254 uint32_t inputOffset = 0;
257 ELEMENT* output = outputVec->data();
259 while (remaining > 0) {
260 const Hashinator::hash_pair<vmesh::GlobalID, vmesh::LocalID>* __restrict__ input = thisMap->expose_bucketdata<
false>();
261 const int current = remaining > blockDim.x ? blockDim.x : remaining;
263 const int active = (tid < current) ? rule(thisMap, input[inputOffset + tid],
threshold, invalidLID, invalidGID) :
false;
264 const auto mask = split::s_warpVote(active == 1, SPLIT_VOTING_MASK);
265 const auto warpCount = split::s_pop_count(mask);
267 warpSums[wid] = warpCount;
273 int activeWARPS = nextPow2(1 + ((current - 1) / WARPLENGTH));
274 auto reduceCounts = [activeWARPS](
int localCount) ->
int {
275 for (
int i = activeWARPS / 2;
i > 0;
i =
i / 2) {
276 localCount += split::s_shuffle_down(localCount,
i, SPLIT_VOTING_MASK);
280 auto localCount = warpSums[w_tid];
281 const int totalCount = reduceCounts(localCount);
283 outputCount = totalCount;
284 outputSize += totalCount;
285 assert((outputSize <= capacity) &&
"extract_GIDs_kernel ran out of capacity!");
286 outputVec->device_resize(outputSize);
291 auto value = warpSums[w_tid];
292 for (uint d = 1; d < warpsPerBlock; d = 2 * d) {
293 int res = split::s_shuffle_up(value, (
int)d, SPLIT_VOTING_MASK);
294 if (tid % warpsPerBlock >= d) {
298 warpSums[w_tid] = value;
301 auto offset = (wid == 0) ? 0 : warpSums[wid - 1];
302 auto pp = split::s_pop_count(mask & ((ONE << w_tid) - ONE));
303 const auto warpTidWriteIndex = offset + pp;
305 if constexpr (FIRSTONLY) {
306 output[warpTidWriteIndex] = input[inputOffset + tid].first;
308 output[warpTidWriteIndex] = input[inputOffset + tid];
313 inputOffset += current;
314 output += outputCount;
315 remaining -= current;
320 outputVec->device_resize(outputSize);
327template <
typename Rule,
typename ELEMENT,
bool FIRSTONLY=false>
329 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>** input_maps,
330 split::SplitVector<ELEMENT> **output_vecs,
334 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>** rule_maps,
335 split::SplitVector<vmesh::GlobalID>** rule_vectors,
339 extract_GIDs_kernel<Rule,ELEMENT,FIRSTONLY><<<nCells, Hashinator::defaults::MAX_BLOCKSIZE, 0, stream>>>(
357template <
typename Rule>
358__global__
void __launch_bounds__(Hashinator::defaults::MAX_BLOCKSIZE, FULLBLOCKS_PER_MP) extract_overflown_kernel(
360 split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>> **output_vecs,
365 const size_t vmeshIndex = blockIdx.x;
369 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* thisMap =
vmeshes[vmeshIndex]->gpu_expose_map();
370 Hashinator::Info *info = thisMap->expose_mapinfo<
false>();
371 split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>> *outputVec = output_vecs[vmeshIndex];
373 if (info->tombstoneCounter == 0) {
375 outputVec->device_resize(0);
379 __shared__ uint32_t warpSums[WARPLENGTH];
380 __shared__ uint32_t outputCount;
381 const int tid = threadIdx.x;
382 const int wid = tid / WARPLENGTH;
383 const int w_tid = tid % WARPLENGTH;
385 const uint warpsPerBlock = blockDim.x / WARPLENGTH;
392 int64_t remaining = thisMap->bucket_count();
393 const uint capacity = outputVec->capacity();
394 uint32_t outputSize = 0;
396 Hashinator::hash_pair<vmesh::GlobalID, vmesh::LocalID> *input = thisMap->expose_bucketdata<
false>();
397 Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>* output = outputVec->data();
400 while (remaining > 0) {
401 int current = remaining > blockDim.x ? blockDim.x : remaining;
403 const int active = (tid < current) ? rule(thisMap, input[tid]) :
false;
404 const auto mask = split::s_warpVote(active == 1, SPLIT_VOTING_MASK);
405 const auto warpCount = split::s_pop_count(mask);
407 warpSums[wid] = warpCount;
413 int activeWARPS = nextPow2(1 + ((current - 1) / WARPLENGTH));
414 auto reduceCounts = [activeWARPS](
int localCount) ->
int {
415 for (
int i = activeWARPS / 2;
i > 0;
i =
i / 2) {
416 localCount += split::s_shuffle_down(localCount,
i, SPLIT_VOTING_MASK);
420 auto localCount = warpSums[w_tid];
421 int totalCount = reduceCounts(localCount);
423 outputCount = totalCount;
424 outputSize += totalCount;
425 assert((outputSize <= capacity) &&
"extract_overflown_kernel ran out of capacity!");
426 outputVec->device_resize(outputSize);
431 auto value = warpSums[w_tid];
432 for (uint d = 1; d < warpsPerBlock; d = 2 * d) {
433 int res = split::s_shuffle_up(value, (
int)d, SPLIT_VOTING_MASK);
434 if (tid % warpsPerBlock >= d) {
438 warpSums[w_tid] = value;
441 auto offset = (wid == 0) ? 0 : warpSums[wid - 1];
442 auto pp = split::s_pop_count(mask & ((ONE << w_tid) - ONE));
443 const auto warpTidWriteIndex = offset + pp;
445 output[warpTidWriteIndex] = input[tid];
447 input[tid].first = emptybucket;
451 output += outputCount;
452 remaining -= current;
457 outputVec->device_resize(outputSize);
458 output_sizes[vmeshIndex] = outputSize;
460 info->currentMaxBucketOverflow = Hashinator::defaults::BUCKET_OVERFLOW;
461 info->fill -= outputSize;
462 info->tombstoneCounter = 0;
466template <
typename Rule>
469 split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>> **overflown_elements,
476 extract_overflown_kernel<Rule><<<nCells, Hashinator::defaults::MAX_BLOCKSIZE, 0, stream>>>(
490 const split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>* __restrict__
const *input_vecs
493 const uint
ti = threadIdx.x;
496 const size_t vmeshIndex = blockIdx.y;
497 const size_t blockIndex = blockIdx.x;
501 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* thisMap =
vmeshes[vmeshIndex]->gpu_expose_map();
502 const split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>* __restrict__ inputVec = input_vecs[vmeshIndex];
504 const size_t inputVecSize = inputVec->size();
505 if (inputVecSize == 0 || blockIndex >= inputVecSize) {
510 #ifdef USE_BATCH_WARPACCESSORS
513 #ifdef DEBUG_SPATIAL_CELL
514 thisMap->warpInsert((inputVec->at(blockIndex)).first,(inputVec->at(blockIndex)).second,b_tid);
516 thisMap->warpInsert(((*inputVec)[blockIndex]).first,((*inputVec)[blockIndex]).second,b_tid);
523 #ifdef DEBUG_SPATIAL_CELL
524 thisMap->set_element((inputVec->at(blockIndex)).first,(inputVec->at(blockIndex)).second);
526 thisMap->set_element(((*inputVec)[blockIndex]).first,((*inputVec)[blockIndex]).second);
532#ifdef USE_BATCH_WARPACCESSORS
541 const split::SplitVector<vmesh::GlobalID>* __restrict__
const *velocity_block_with_content_lists,
542 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>**
allMaps
546 const uint nCells = gridDim.y;
548 const uint blockiStart = blockIdx.x;
550 const uint ti = threadIdx.x;
557 const split::SplitVector<vmesh::GlobalID>* __restrict__ velocity_block_with_content_list = velocity_block_with_content_lists[
cellIndex];
558 const vmesh::GlobalID* __restrict__ velocity_block_with_content_list_data = velocity_block_with_content_list->data();
559 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* vbwcl_map =
allMaps[2*
cellIndex];
560 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* vbwncl_map =
allMaps[2*
cellIndex+1];
561 const vmesh::LocalID nBlocks = velocity_block_with_content_list->size();
566 if (blocki >= nBlocks) {
577 #ifdef __HIP_PLATFORM_HCC___
580 for (
int i=0;
i<max_i;
i++) {
581 int offsetIndex = offsetIndex1 + 13*
i;
583 if (offsetIndex > 12) {
586 const int offset_vx = (offsetIndex % 3) - 1;
587 const int offset_vy = ((offsetIndex / 3) % 3) - 1;
588 const int offset_vz = (offsetIndex / 9) - 1;
590 #ifdef DEBUG_SPATIAL_CELL
591 const vmesh::GlobalID GID = velocity_block_with_content_list->at(blocki);
593 const vmesh::GlobalID GID = velocity_block_with_content_list_data[blocki];
596 vmesh->getIndices(GID,ind0,ind1,ind2);
597 const int nind0 = ind0 + offset_vx;
598 const int nind1 = ind1 + offset_vy;
599 const int nind2 = ind2 + offset_vz;
601 =
vmesh->getGlobalID(nind0,nind1,nind2);
602 if (nGID !=
vmesh->invalidGlobalID()) {
606 const bool newlyadded = vbwcl_map->warpInsert_V<
true>(nGID,LID, w_tid);
609 if ( LID !=
vmesh->invalidLocalID()) {
611 vbwncl_map->warpErase(nGID, w_tid);
629 const split::SplitVector<vmesh::GlobalID>* __restrict__
const *velocity_block_with_content_lists,
630 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>**
allMaps,
631 const uint warpsPerBlockBatchHalo
637 const uint blockiStart = blockIdx.x*warpsPerBlockBatchHalo+threadIdx.y;
638 const uint
ti = threadIdx.x;
650 const split::SplitVector<vmesh::GlobalID>* __restrict__ velocity_block_with_content_list = velocity_block_with_content_lists[
cellIndex];
651 const vmesh::GlobalID* __restrict__ velocity_block_with_content_list_data = velocity_block_with_content_list->data();
652 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* vbwcl_map =
allMaps[2*
cellIndex];
653 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* vbwncl_map =
allMaps[2*
cellIndex+1];
654 const vmesh::LocalID nBlocks = velocity_block_with_content_list->size();
659 if (blocki >= nBlocks) {
662 int offsetIndex =
ti;
664 if (offsetIndex > 12) {
667 const int offset_vx = (offsetIndex % 3) - 1;
668 const int offset_vy = ((offsetIndex / 3) % 3) - 1;
669 const int offset_vz = (offsetIndex / 9) - 1;
671 #ifdef DEBUG_SPATIAL_CELL
672 const vmesh::GlobalID GID = velocity_block_with_content_list->at(blocki);
674 const vmesh::GlobalID GID = velocity_block_with_content_list_data[blocki];
677 vmesh->getIndices(GID,ind0,ind1,ind2);
678 const int nind0 = ind0 + offset_vx;
679 const int nind1 = ind1 + offset_vy;
680 const int nind2 = ind2 + offset_vz;
682 =
vmesh->getGlobalID(nind0,nind1,nind2);
683 if (nGID !=
vmesh->invalidGlobalID()) {
687 const bool newlyadded = vbwcl_map->set_element<
true>(nGID,LID);
690 if ( LID !=
vmesh->invalidLocalID()) {
692 vbwncl_map->device_erase(nGID);
702#ifdef USE_BATCH_WARPACCESSORS
707 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>**
allMaps,
708 const split::SplitVector<vmesh::GlobalID>* __restrict__
const *neigh_velocity_block_with_content_lists
710 const uint nCells = gridDim.y;
711 const uint maxNeighbours = gridDim.z;
713 const uint neighIndex = blockIdx.y * maxNeighbours + blockIdx.z;
720 if (neigh_velocity_block_with_content_lists[neighIndex] == 0) {
724 const int ti = threadIdx.x;
729 const int blockiStart = blockIdx.x * blockWidth;
731 const split::SplitVector<vmesh::GlobalID>* __restrict__ velocity_block_with_content_list = neigh_velocity_block_with_content_lists[neighIndex];
732 const int nBlocks = velocity_block_with_content_list->size();
734 for (
int blocki = blockiStart + w_id; blocki < blockiStart+blockWidth; blocki += blockWidth) {
736 if (blocki < nBlocks) {
738 const vmesh::GlobalID* __restrict__ velocity_block_with_content_list_data = velocity_block_with_content_list->data();
739 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* vbwcl_map =
allMaps[2*
cellIndex];
740 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* vbwncl_map =
allMaps[2*
cellIndex+1];
742 #ifdef DEBUG_SPATIAL_CELL
743 const vmesh::GlobalID nGID = velocity_block_with_content_list->at(blocki);
745 const vmesh::GlobalID nGID = velocity_block_with_content_list_data[blocki];
750 const bool newlyadded = vbwcl_map->warpInsert_V<
true>(nGID,LID, w_tid);
753 if ( LID !=
vmesh->invalidLocalID()) {
755 vbwncl_map->warpErase(nGID, w_tid);
770 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>**
allMaps,
771 const split::SplitVector<vmesh::GlobalID>* __restrict__
const *neigh_velocity_block_with_content_lists
775 const uint maxNeighbours = gridDim.z;
777 const uint neighIndex = blockIdx.y * maxNeighbours + blockIdx.z;
780 const split::SplitVector<vmesh::GlobalID>* __restrict__ velocity_block_with_content_list = neigh_velocity_block_with_content_lists[neighIndex];
783 if (vmeshCellIndex == 0) {
787 if (velocity_block_with_content_list == 0) {
791 const int blockWidth = blockDim.x;
792 const int ti = threadIdx.x;
794 const int nBlocks = velocity_block_with_content_list->size();
797 const int blocki = blockIdx.x * blockWidth +
ti;
799 if (blocki >= nBlocks) {
802 const vmesh::GlobalID* __restrict__ velocity_block_with_content_list_data = velocity_block_with_content_list->data();
803 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* vbwcl_map =
allMaps[2*
cellIndex];
804 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>* vbwncl_map =
allMaps[2*
cellIndex+1];
806 #ifdef DEBUG_SPATIAL_CELL
807 const vmesh::GlobalID nGID = velocity_block_with_content_list->at(blocki);
809 const vmesh::GlobalID nGID = velocity_block_with_content_list_data[blocki];
814 const bool newlyadded = vbwcl_map->set_element<
true>(nGID,LID);
817 if ( LID != vmeshCellIndex->invalidLocalID()) {
819 vbwncl_map->device_erase(nGID);
831 split::SplitVector<vmesh::GlobalID>** dev_list_with_replace_new,
832 split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>** dev_list_delete,
833 split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>** dev_list_to_replace,
834 split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>** dev_list_with_replace_old,
840 Real* dev_rhoLossAdjust
849 split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>* list_delete = dev_list_delete[
cellIndex];
850 split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>* list_to_replace = dev_list_to_replace[
cellIndex];
855 const vmesh::LocalID nToRemove = list_delete->size() + list_to_replace->size();
856 const vmesh::LocalID nBlocksAfterAdjust = nBlocksBeforeAdjust + nToAdd - nToRemove;
857 const vmesh::LocalID nBlocksToChange = nToAdd > nToRemove ? nToAdd : nToRemove;
860 dev_nBefore[
cellIndex] = nBlocksBeforeAdjust;
861 dev_nAfter[
cellIndex] = nBlocksAfterAdjust;
862 dev_nBlocksToChange[
cellIndex] = nBlocksToChange;
864 if (nBlocksAfterAdjust > nBlocksBeforeAdjust) {
865 if ((nBlocksAfterAdjust <= vmesh->capacity()) && (nBlocksAfterAdjust <= blockContainer->capacity())) {
867 vmesh->device_setNewSize(nBlocksAfterAdjust);
868 blockContainer->
setNewSize(nBlocksAfterAdjust);
891 vmesh->device_setNewSize(nBlocksAfterAdjust);
892 blockContainer->
setNewSize(nBlocksAfterAdjust);
900 const split::SplitVector<vmesh::GlobalID>* __restrict__
const *dev_list_with_replace_new,
901 const split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>* __restrict__
const *dev_list_delete,
902 const split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>* __restrict__
const *dev_list_to_replace,
903 const split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>* __restrict__
const *dev_list_with_replace_old,
907 Real* dev_rhoLossAdjust
917 const split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>* __restrict__ list_delete = dev_list_delete[
cellIndex];
918 const split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>* __restrict__ list_to_replace = dev_list_to_replace[
cellIndex];
919 const split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>* __restrict__ list_with_replace_old = dev_list_with_replace_old[
cellIndex];
925 if (blockIdx.x >= nBlocksToChange) {
928 const uint ti = threadIdx.x;
933 const int b_tid =
ti %
WID3;
938 const vmesh::LocalID n_with_replace_old = list_with_replace_old->size();
948 if (
index < n_delete) {
949 #ifdef DEBUG_SPATIAL_CELL
957 #ifdef DEBUG_SPATIAL_CELL
958 if (rmGID ==
vmesh->invalidGlobalID()) {
959 if (rmLID !=
vmesh->invalidLocalID()) {
962 printf(
"Removing blocks: Valid LID %u but invalid GID!\n",rmLID);
966 printf(
"Removing blocks: Invalid LID and GID!\n");
971 if (rmLID ==
vmesh->invalidLocalID()) {
972 if (rmGID !=
vmesh->invalidGlobalID()) {
975 printf(
"Removing blocks: Valid GID %ul but invalid LID!\n",rmGID);
980 if ((
unsigned long)rmLID >= (
unsigned long)nBlocksBeforeAdjust) {
982 printf(
"Trying to outright remove block which has LID %ul >= nBlocksBeforeAdjust %ul!\n",rmLID,nBlocksBeforeAdjust);
986 if ((
unsigned long)rmLID < (
unsigned long)nBlocksAfterAdjust) {
988 printf(
"Trying to outright remove block which has LID %u smaller than nBlocksAfterAdjust %u!\n",rmLID,nBlocksAfterAdjust);
1001 massloss[
ti] = rm_avgs[b_tid]*rm_DV3;
1004 for (
int s=
WID3/2;
s>0;
s>>=1) {
1006 massloss[
ti] += massloss[
ti +
s];
1017 #ifdef USE_BATCH_WARPACCESSORS
1018 vmesh->warpDeleteBlock(rmGID,rmLID,b_tid);
1021 vmesh->deleteBlock(rmGID,rmLID);
1033 if (
index < n_to_replace) {
1034 #ifdef DEBUG_SPATIAL_CELL
1043 #ifdef DEBUG_SPATIAL_CELL
1044 if (rmGID ==
vmesh->invalidGlobalID()) {
1045 if (rmLID !=
vmesh->invalidLocalID()) {
1048 printf(
"Replacing blocks: Valid LID %u but invalid GID!\n",rmLID);
1052 printf(
"Replacing blocks: Invalid LID and GID!\n");
1057 if (rmLID ==
vmesh->invalidLocalID()) {
1058 if (rmGID !=
vmesh->invalidGlobalID()) {
1061 printf(
"Replacing blocks: Valid GID %ul but invalid LID!\n",rmGID);
1066 if (rmLID >= nBlocksBeforeAdjust) {
1068 printf(
"Trying to replace block which has LID %ul >= nBlocksBeforeAdjust %ul!\n",rmLID,nBlocksBeforeAdjust);
1081 massloss[
ti] = rm_avgs[b_tid]*rm_DV3;
1084 for (
int s=
WID3/2;
s>0;
s>>=1) {
1086 massloss[
ti] += massloss[
ti +
s];
1101 if (
index < n_with_replace_old) {
1102 #ifdef DEBUG_SPATIAL_CELL
1103 replaceGID = (list_with_replace_old->at(
index)).first;
1104 replaceLID = (list_with_replace_old->at(
index)).second;
1106 replaceGID = ((*list_with_replace_old)[
index]).first;
1107 replaceLID = ((*list_with_replace_old)[
index]).second;
1110 Realf* repl_avgs = blockContainer->
getData(replaceLID);
1112 rm_avgs[b_tid] = repl_avgs[b_tid];
1114 rm_block_parameters[b_tid] = repl_block_parameters[b_tid];
1120 #ifdef DEBUG_SPATIAL_CELL
1123 replaceGID = (*list_with_replace_new)[
index - n_with_replace_old];
1125 replaceLID =
vmesh->invalidLocalID();
1135 #ifdef USE_BATCH_WARPACCESSORS
1136 vmesh->warpReplaceBlock(rmGID,rmLID,replaceGID,b_tid);
1139 vmesh->replaceBlock(rmGID,rmLID,replaceGID);
1142 #ifdef DEBUG_SPATIAL_CELL
1144 if (
vmesh->getGlobalID(rmLID) != replaceGID) {
1146 printf(
"Error! Replacing did not result in wanted GID at old LID in update_velocity_blocks_kernel! \n");
1150 if (
vmesh->getLocalID(replaceGID) != rmLID) {
1152 printf(
"Error! Replacing did not result in old LID at replaced GID in update_velocity_blocks_kernel! \n");
1160 index -= n_to_replace;
1167 const uint add_index =
index + (n_to_replace - n_with_replace_old);
1168 if (add_index < n_with_replace_new) {
1169 #ifdef DEBUG_SPATIAL_CELL
1171 if (
vmesh->getLocalID(addGID) !=
vmesh->invalidLocalID()) {
1173 printf(
"Trying to add new GID %u to mesh which already contains it! index=%u addindex=%u\n",addGID,
index,add_index);
1185 #ifdef DEBUG_SPATIAL_CELL
1186 if (addGID ==
vmesh->invalidGlobalID()) {
1187 printf(
"Error! invalid addGID!\n");
1190 if (addLID ==
vmesh->invalidLocalID()) {
1191 printf(
"Error! invalid addLID!\n");
1197 add_avgs[b_tid] = 0;
1205 #ifdef USE_BATCH_WARPACCESSORS
1206 vmesh->warpPlaceBlock(addGID,addLID,b_tid);
1209 vmesh->placeBlock(addGID,addLID);
1212 #ifdef DEBUG_SPATIAL_CELL
1214 if (
vmesh->getGlobalID(addLID) ==
vmesh->invalidGlobalID()) {
1215 printf(
"Error! invalid GID after add from addLID!\n");
1218 if (
vmesh->getLocalID(addGID) ==
vmesh->invalidLocalID()) {
1219 printf(
"Error! invalid LID after add from addGID!\n");
1228 printf(
"Error! Fall through in batch_update_velocity_blocks_kernel! index %u nBlocksBeforeAdjust %u nBlocksAfterAdjust %u \n",
1229 index,nBlocksBeforeAdjust,nBlocksAfterAdjust);
1238 Real* dev_mass_scale
1242 const int blocki = blockIdx.x;
1243 const uint ti = threadIdx.x;
1249 const uint blockLID = blocki;
1251 const uint VBC_size = blockContainer->
size();
1252 if (blockLID > VBC_size || cell_mass_scale <= 0) {
1258 data[b_tid] = data[b_tid] * cell_mass_scale;
#define gpuPeekAtLastError
#define gpuKernelAny(mask, input)
__global__ void batch_update_velocity_halo_kernel(const vmesh::VelocityMesh *__restrict__ const *vmeshes, const split::SplitVector< vmesh::GlobalID > *__restrict__ const *velocity_block_with_content_lists, Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > **allMaps, const uint warpsPerBlockBatchHalo)
#define warpsPerBlockBatchContent
__global__ void batch_resize_vbc_kernel_pre(vmesh::VelocityMesh **vmeshes, vmesh::VelocityBlockContainer **blockContainers, split::SplitVector< vmesh::GlobalID > **dev_list_with_replace_new, split::SplitVector< Hashinator::hash_pair< vmesh::GlobalID, vmesh::LocalID > > **dev_list_delete, split::SplitVector< Hashinator::hash_pair< vmesh::GlobalID, vmesh::LocalID > > **dev_list_to_replace, split::SplitVector< Hashinator::hash_pair< vmesh::GlobalID, vmesh::LocalID > > **dev_list_with_replace_old, vmesh::LocalID *dev_nBefore, vmesh::LocalID *dev_nAfter, vmesh::LocalID *dev_nBlocksToChange, vmesh::LocalID *dev_resizeSuccess, Real *dev_rhoLossAdjust)
__global__ void batch_resize_vbc_kernel_post(vmesh::VelocityMesh **vmeshes, vmesh::VelocityBlockContainer **blockContainers, vmesh::LocalID *dev_nAfter)
__global__ void __launch_bounds__(WID3, WID3S_PER_MP) batch_update_velocity_block_content_lists_kernel(const vmesh
void extract_GIDs_kernel_launcher(Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > **input_maps, split::SplitVector< ELEMENT > **output_vecs, vmesh::LocalID *output_sizes, Rule rule, vmesh::VelocityMesh **rule_meshes, Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > **rule_maps, split::SplitVector< vmesh::GlobalID > **rule_vectors, const uint nCells, gpuStream_t stream)
void clean_tombstones_launcher(vmesh::VelocityMesh **vmeshes, split::SplitVector< Hashinator::hash_pair< vmesh::GlobalID, vmesh::LocalID > > **overflown_elements, vmesh::LocalID *output_sizes, Rule rule, const uint nCells, gpuStream_t stream)
ARCH_HOSTDEV vmesh::LocalID size() const
ARCH_HOSTDEV Real * getParameters()
ARCH_HOSTDEV Realf * getData()
ARCH_HOSTDEV bool setNewSize(const vmesh::LocalID newSize)
__global__ void vmesh::VelocityMesh **__restrict__ vmeshes
__global__ void vmesh::VelocityMesh **__restrict__ ColumnOffsets split::SplitVector< vmesh::GlobalID > Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > ** allMaps
split::SplitVector< vmesh::GlobalID > * list_with_replace_new
__global__ void vmesh::VelocityMesh **__restrict__ ColumnOffsets split::SplitVector< vmesh::GlobalID > Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > const uint *__restrict__ const Realf const int const int const Realf const Realf vmesh::LocalID * dev_resizeSuccess
__global__ void const Realf const uint *__restrict__ const uint *__restrict__ const vmesh::GlobalID *__restrict__ const uint const uint const uint const Realf threshold
@ N_VELOCITY_BLOCK_PARAMS