34#ifdef USE_WARPACCESSORS
35 #define USE_TRANS_WARPACCESSORS
40 for (
int index=-VLASOV_STENCIL_WIDTH;
index<VLASOV_STENCIL_WIDTH+1; ++
index) {
100 const uint startingBlockIndex = blockIdx.y*gridDim.x;
105 const vmesh::LocalID ti = (threadIdx.z)*blockDim.x*blockDim.y + threadIdx.y*blockDim.x + threadIdx.x;
120 printf(
" Wrong dimension, abort\n");
135 const uint blockGID =
allBlocks[thisBlockIndex];
137 uint nBin = blockIdx.z;
139 for (uint pencilIndex = 0; pencilIndex <
dev_binSize[nBin]; pencilIndex++) {
145 uint nonEmptyBlocks = 0;
147 for (uint celli = 0; celli < lengthOfPencil; celli++) {
151 #ifdef USE_TRANS_WARPACCESSORS
157 if (blockLID !=
vmesh->invalidLocalID()) {
158 #ifdef DEBUG_VLASIATOR
161 if ((blockLID>=meshSize) || (blockLID>=VBCSize)) {
163 printf(
"Error in translation: trying to access LID %ul but sizes are vmesh %ul VBC %ul\n",blockLID,meshSize,VBCSize);
172 thisPencilOrderedSource[celli *
WID3 +
ti]
173 = (cellContainer->
getData(blockLID))[
ti];
179 thisPencilOrderedSource[celli *
WID3 +
ti] = (
Realf)(0.0);
191 for (uint pencilIndex = 0; pencilIndex <
dev_binSize[nBin]; pencilIndex++) {
195 for (uint celli = 0; celli < lengthOfPencil; celli++) {
212 randovmesh->getIndicesX(blockGID, blockIndicesD);
213 }
else if (dimension==1) {
214 randovmesh->getIndicesY(blockGID, blockIndicesD);
215 }
else if (dimension==2) {
216 randovmesh->getIndicesZ(blockGID, blockIndicesD);
223 for (uint pencilIndex = 0; pencilIndex <
dev_binSize[nBin]; pencilIndex++) {
233 for (uint
i = VLASOV_STENCIL_WIDTH;
i < lengthOfPencil-VLASOV_STENCIL_WIDTH;
i++){
251 const bool positiveTranslationDirection = (z_translation > (
Realf)(0.0));
259 z_1 = positiveTranslationDirection ? (
Realf)(1.0) - z_translation : (
Realf)(0.0);
260 z_2 = positiveTranslationDirection ? (
Realf)(1.0) : - z_translation;
262 #ifdef DEBUG_VLASIATOR
264 assert( 0 &&
"Error in translation, CFL condition violated.");
275 thisPencilOrderedSource + (
i - VLASOV_STENCIL_WIDTH) *
WID3,
278 const Realf ngbr_target_density =
279 z_2 * ( a[0] + z_2 * ( a[1] + z_2 * a[2] ) ) -
280 z_1 * ( a[0] + z_1 * ( a[1] + z_1 * a[2] ) );
287 if (areaRatio && block_data) {
288 const Realf selfContribution = (thisPencilOrderedSource[
i *
WID3 +
ti] - ngbr_target_density) * areaRatio;
290 block_data[
ti] += selfContribution;
292 if (areaRatio_p1 && block_data_p1) {
293 const Realf p1Contribution = (positiveTranslationDirection ? ngbr_target_density
296 block_data_p1[
ti] += p1Contribution;
298 if (areaRatio_m1 && block_data_m1) {
299 const Realf m1Contribution = (!positiveTranslationDirection ? ngbr_target_density
302 block_data_m1[
ti] += m1Contribution;
319#ifdef USE_WARPACCESSORS
323 const uint nAllCells)
325 const int ti = threadIdx.x;
326 const int indexInBlock = threadIdx.y;
330 const uint thisVmeshSize = thisVmesh->size();
331 const uint blockIndex = blockIndexBase + indexInBlock;
332 if (blockIndex < thisVmeshSize) {
343 const uint nAllCells)
345 const int indexInBlock = threadIdx.x;
349 const uint thisVmeshSize = thisVmesh->size();
350 const uint blockIndex = blockIndexBase + indexInBlock;
351 if (blockIndex < thisVmeshSize) {
373 const vector<CellID>& localPropagatedCells,
374 const vector<CellID>& remoteTargetCells,
375 std::vector<uint>& nPencilsLB,
376 const uint dimension,
380 phiprof::Timer setupTimer {
"trans-amr-setup"};
383 if(localPropagatedCells.size() == 0) {
389 vector<CellID> allCells(localPropagatedCells);
390 allCells.insert(allCells.end(), remoteTargetCells.begin(), remoteTargetCells.end());
391 const uint nAllCells = allCells.size();
393 phiprof::Timer allocateTimer {
"trans-amr-allocs"};
411 allocateTimer.stop();
414 phiprof::Timer maxMeshSizeTimer {
"trans-amr-find-maxmesh"};
415 uint largestFoundMeshSize = 0;
416 int checkMeshId {phiprof::initializeTimer(
"trans-amr-checkMesh")};
419 uint thread_largestFoundMeshSize = 0;
421 for(uint celli = 0; celli < nAllCells; celli++){
423 const uint thisMeshSize = mpiGrid[allCells[celli]]->get_velocity_mesh(popID)->size();
424 thread_largestFoundMeshSize = thisMeshSize > thread_largestFoundMeshSize ? thisMeshSize : thread_largestFoundMeshSize;
425 #ifdef DEBUG_VLASIATOR
426 phiprof::Timer checkMeshTimer {checkMeshId};
427 if (!mpiGrid[allCells[celli]]->checkMesh(popID)) {
428 printf(
"GPU TRANS MAP AMR check of mesh for popID %d cell %lu failed!\n",popID,allCells[celli]);
434 largestFoundMeshSize = largestFoundMeshSize > thread_largestFoundMeshSize ? largestFoundMeshSize : thread_largestFoundMeshSize;
437 maxMeshSizeTimer.stop();
440 if(largestFoundMeshSize == 0) {
444 allocateTimer.start();
449 allocateTimer.stop();
452 phiprof::Timer pencilCountTimer {
"trans-amr-count-pencils"};
454 for (uint
i=0;
i<localPropagatedCells.size();
i++) {
456 nPencilsLB[
i] += myPencilCount;
457 nPencilsLB[nPencilsLB.size()-1] += myPencilCount;
460 pencilCountTimer.stop();
462 phiprof::Timer buildTimer {
"trans-amr-buildBlockList"};
466#ifdef USE_WARPACCESSORS
467 const uint maxBlocksPerCell = 1 + ((largestFoundMeshSize - 1) /
WARPSPERBLOCK);
468 dim3 gatherdims_blocks(nAllCells,maxBlocksPerCell,1);
470 gather_union_of_blocks_kernel_WA<<<gatherdims_blocks, gatherdims_threads, 0, bgStream>>> (
473 dim3 gatherdims_blocks(nAllCells,maxBlocksPerCell,1);
475 gather_union_of_blocks_kernel<<<gatherdims_blocks, gatherdims_threads, 0, bgStream>>> (
485 phiprof::Timer gatherPointerTimer {
"trans-amr-gather-meshpointers"};
490 #pragma omp parallel for
491 for (uint pencili = 0; pencili <
nPencils; ++pencili) {
495 for (
int i = 0;
i < L;
i++) {
497 host_allPencilsMeshes[start+
i] = mpiGrid[thisCell]->dev_get_velocity_mesh(popID);
498 host_allPencilsContainers[start+
i] = mpiGrid[thisCell]->dev_get_velocity_blocks(popID);
510 gatherPointerTimer.stop();
513 allocateTimer.start();
515 Hashinator::Info mapInfo;
520 allocateTimer.stop();
522 phiprof::Timer buildTimer2 {
"trans-amr-buildBlockList-2"};
525 split::SplitInfo unionInfo;
544 const uint nBlocksPerAllocation = currentAllocation /
sumOfLengths;
547 const uint totalPerAllocation = 1 + ((
nAllBlocks - 1) / numAllocations);
549 const uint nGpuBlocks = std::min(nBlocksPerAllocation,totalPerAllocation);
552 phiprof::Timer bufferTimer {
"trans-amr-buffers"};
555 allocateTimer.start();
563 allocateTimer.stop();
571 phiprof::Timer mappingTimer {
"trans-amr-mapping"};
576 translation_kernel<<<grid, block, 0, bgStream>>> (
592 dev_pencilBlocksCount,
614 const int NO_SIBLINGS = 0;
615 if(mpiGrid.get_refinement_level(cellid) == 0) {
620 CellID parent = mpiGrid.get_parent(cellid);
623 std::cerr<<
"Invalid parent id"<<std::endl;
630 vector<CellID> siblings = mpiGrid.get_all_children(parent);
631 auto location = std::find(siblings.begin(),siblings.end(),cellid);
632 auto index = std::distance(siblings.begin(), location);
634 std::cerr<<
"Invalid parent id"<<std::endl;
650 const int blocki = blockIdx.x;
651 const int i = threadIdx.x;
652 const int j = threadIdx.y;
653 const int k = threadIdx.z;
659 blockData[blocki *
WID3 +
ti] += neighborData[blocki *
WID3 +
ti];
674 dccrg::Dccrg<SpatialCell,dccrg::Cartesian_Geometry>& mpiGrid,
675 const uint dimension,
681 MPI_Comm_size(MPI_COMM_WORLD,&mpiProcs);
696 int neighborhood = 0;
731 vector<CellID> receive_cells;
733 vector<CellID> receive_origin_cells;
734 vector<uint> receive_origin_index;
736 phiprof::Timer updateRemoteTimerPre {
"trans-amr-remotes-setup-getcells"};
738 #pragma omp parallel for
739 for (
auto rc : remote_cells) {
752 #pragma omp parallel for
753 for (
auto lc : local_cells) {
763 updateRemoteTimerPre.stop();
765 vector<Realf*> receiveBuffers;
766 vector<Realf*> sendBuffers;
768 phiprof::Timer updateRemoteTimer0 {
"trans-amr-remotes-setup-localcells"};
769 for (
auto c : local_cells) {
774 vector<CellID> p_nbrs;
775 vector<CellID> n_nbrs;
776 for (
const auto& [neighbor, dir] : mpiGrid.get_face_neighbors_of(
c)) {
777 if(dir == ((
int)dimension + 1) * direction) {
778 p_nbrs.push_back(neighbor);
780 if(dir == -1 * ((
int)dimension + 1) * direction) {
781 n_nbrs.push_back(neighbor);
789 if (!all_of(p_nbrs.begin(), p_nbrs.end(), [&mpiGrid](
CellID i){return mpiGrid.is_local(i);})) {
790 phiprof::Timer updateRemoteTimer1 {
"trans-amr-remotes-setup-sends"};
792 for (
const auto nbr : p_nbrs) {
805 if(mpiGrid.get_refinement_level(
c) >= mpiGrid.get_refinement_level(nbr)) {
806 sendIndex = mySiblingIndex;
816 if(send_cells.find(nbr) == send_cells.end()) {
819 send_cells.insert(nbr);
828 sendBuffers.push_back(0);
843 if (!all_of(n_nbrs.begin(), n_nbrs.end(), [&mpiGrid](
CellID i){return mpiGrid.is_local(i);})) {
844 phiprof::Timer updateRemoteTimer2 {
"trans-amr-remotes-setup-receives"};
846 for (
const auto nbr : n_nbrs) {
863 if(mpiGrid.get_refinement_level(nbr) >= mpiGrid.get_refinement_level(
c)) {
868 receiveBuffers.push_back(0);
876 recvIndex = mySiblingIndex;
879 auto mySiblings = mpiGrid.get_all_children(mpiGrid.get_parent(
c));
880 auto myIndices = mpiGrid.mapping.get_indices(
c);
885 auto sibling = mySiblings.at(i_sib);
886 auto sibIndices = mpiGrid.mapping.get_indices(sibling);
887 auto* scell = mpiGrid[sibling];
892 && mpiGrid.get_process(sibling) != mpiGrid.get_process(nbr)
893 && myIndices.at(dimension) == sibIndices.at(dimension)
899 receiveBuffers.push_back(0);
909 receive_cells.push_back(
c);
910 receive_origin_cells.push_back(nbr);
911 receive_origin_index.push_back(recvIndex);
916 updateRemoteTimer0.stop();
918 MPI_Barrier(MPI_COMM_WORLD);
919 phiprof::Timer updateRemoteTimer3 {
"trans-amr-remotes-MPI"};
924 mpiGrid.update_copies_of_remote_neighbors(neighborhood);
925 updateRemoteTimer3.stop();
927 MPI_Barrier(MPI_COMM_WORLD);
931 if (receive_cells.size() != 0) {
932 phiprof::Timer updateRemoteTimerIncrement {
"trans-amr-remotes-increment"};
933 for (
size_t c = 0;
c < receive_cells.size(); ++
c) {
935 SpatialCell* origin_cell = mpiGrid[receive_origin_cells[
c]];
936 if (!receive_cell || !origin_cell) {
962 vector<CellID> send_cells_vector(send_cells.begin(), send_cells.end());
963 for (uint
c = 0;
c < send_cells_vector.size();
c++) {
972 phiprof::Timer updateRemoteTimerFree {
"trans-amr-remotes-free"};
973 for (
auto p : receiveBuffers) {
976 for (
auto p : sendBuffers) {
979 updateRemoteTimerFree.stop();
set(gca, 'YDir', 'normal')
#define gpuPeekAtLastError
cudaStream_t gpuStreamList[]
#define gpuStreamSynchronize
#define gpuMemcpyHostToDevice
#define gpuMemPrefetchAsync
#define gpuDeviceSynchronize
vmesh::LocalID get_number_of_velocity_blocks(const uint popID) const
std::array< Realf *, MAX_NEIGHBORS_PER_DIM > neighbor_block_data
static bool setCommunicatedSpecies(const uint popID)
static void set_mpi_transfer_type(const uint64_t type, bool atSysBoundaries=false)
std::array< vmesh::LocalID, MAX_NEIGHBORS_PER_DIM > neighbor_number_of_blocks
Realf * get_data(const uint popID)
ARCH_HOSTDEV vmesh::LocalID size() const
ARCH_HOSTDEV Realf * getData()
std::array< setOfPencils, 3 > DimensionPencils
bool do_translate_cell(const SpatialCell *const SC)
#define MAX_NEIGHBORS_PER_DIM
GPUMemoryManager gpuMemoryManager
split::SplitVector< vmesh::GlobalID > * dev_unionOfBlocks
__host__ int gpu_getDevice()
Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > * dev_unionOfBlocksSet
split::SplitVector< vmesh::GlobalID > * unionOfBlocks
__host__ void gpu_trans_allocate(cuint nAllCells, cuint largestVmesh, cuint unionSetSize)
Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > * unionOfBlocksSet
__host__ gpuStream_t gpu_getStream()
__host__ uint gpu_vlasov_getSmallestAllocation()
__host__ uint gpu_getMaxThreads()
__host__ uint gpu_getAllocationCount()
__host__ void gpu_vlasov_allocate(const uint maxBlockCount)
#define SESSION_HOST_ALLOCATE(object, type, member, bytes)
#define SESSION_ALLOCATE(object, type, member, bytes)
#define GET_SESSION_POINTER(object, type, member)
#define GET_SESSION_HOST_POINTER(object, type, member)
#define GET_POINTER(object, type, member)
__global__ void const Realf const uint *__restrict__ const uint *__restrict__ const vmesh::GlobalID *__restrict__ const uint const uint const uint const Realf const vmesh::VelocityMesh *__restrict__ const * dev_allPencilsMeshes
__global__ void const Realf const uint *__restrict__ const uint *__restrict__ const vmesh::GlobalID *__restrict__ const uint const uint const uint const Realf threshold
const vmesh::VelocityMesh *__restrict__ randovmesh
__global__ void const Realf const uint *__restrict__ const uint *__restrict__ pencilStarts
__global__ void const Realf const uint *__restrict__ const uint *__restrict__ const vmesh::GlobalID *__restrict__ const uint const uint nPencils
__global__ void const Realf const uint *__restrict__ const uint *__restrict__ const vmesh::GlobalID *__restrict__ const uint const uint const uint const Realf const vmesh::VelocityMesh *__restrict__ const vmesh::VelocityBlockContainer Realf Realf const Realf *__restrict__ const Realf *__restrict__ uint uint uint uint const uint numberOfBins
__global__ void const Realf const uint *__restrict__ const uint *__restrict__ const vmesh::GlobalID *__restrict__ const uint const uint const uint const Realf const vmesh::VelocityMesh *__restrict__ const vmesh::VelocityBlockContainer Realf Realf const Realf *__restrict__ const Realf *__restrict__ pencilRatios
__global__ void const Realf const uint *__restrict__ const uint *__restrict__ const vmesh::GlobalID *__restrict__ const uint const uint const uint const Realf const vmesh::VelocityMesh *__restrict__ const vmesh::VelocityBlockContainer Realf Realf const Realf *__restrict__ const Realf *__restrict__ uint uint uint * dev_binStart
__global__ void const Realf const uint *__restrict__ const uint *__restrict__ const vmesh::GlobalID *__restrict__ allBlocks
__global__ void const Realf const uint *__restrict__ const uint *__restrict__ const vmesh::GlobalID *__restrict__ const uint nAllBlocks
__global__ void const Realf const uint *__restrict__ const uint *__restrict__ const vmesh::GlobalID *__restrict__ const uint const uint const uint const Realf const vmesh::VelocityMesh *__restrict__ const vmesh::VelocityBlockContainer Realf Realf const Realf *__restrict__ const Realf *__restrict__ uint * pencilBlocksCount
static __global__ void remote_increment_kernel(Realf *blockData, Realf *neighborData, vmesh::LocalID nBlocks)
__global__ void const Realf const uint *__restrict__ pencilLengths
const uint pencilBlocksCountOffset
Realf * pencilOrderedSource
__global__ void const Realf const uint *__restrict__ const uint *__restrict__ const vmesh::GlobalID *__restrict__ const uint const uint const uint const Realf const vmesh::VelocityMesh *__restrict__ const vmesh::VelocityBlockContainer ** dev_allPencilsContainers
__global__ void const Realf const uint *__restrict__ const uint *__restrict__ const vmesh::GlobalID *__restrict__ const uint const uint const uint sumOfLengths
const uint pencilOrderedSourceOffset
__global__ void const Realf const uint *__restrict__ const uint *__restrict__ const vmesh::GlobalID *__restrict__ const uint const uint const uint const Realf const vmesh::VelocityMesh *__restrict__ const vmesh::VelocityBlockContainer Realf Realf const Realf *__restrict__ pencilDZ
__global__ void const Realf const uint *__restrict__ const uint *__restrict__ const vmesh::GlobalID *__restrict__ const uint const uint const uint const Realf const vmesh::VelocityMesh *__restrict__ const vmesh::VelocityBlockContainer Realf ** pencilBlockData
__global__ void const Realf const uint *__restrict__ const uint *__restrict__ const vmesh::GlobalID *__restrict__ const uint const uint const uint const Realf const vmesh::VelocityMesh *__restrict__ const vmesh::VelocityBlockContainer Realf Realf const Realf *__restrict__ const Realf *__restrict__ uint uint uint uint * dev_binSize
int get_sibling_index(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, const CellID &cellid)
__global__ void const Realf const uint *__restrict__ const uint *__restrict__ const vmesh::GlobalID *__restrict__ const uint const uint const uint const Realf const vmesh::VelocityMesh *__restrict__ const vmesh::VelocityBlockContainer Realf Realf const Realf *__restrict__ const Realf *__restrict__ uint uint * dev_pencilsInBin
__global__ void const Realf const uint *__restrict__ const uint *__restrict__ const vmesh::GlobalID *__restrict__ const uint const uint const uint const Realf const vmesh::VelocityMesh *__restrict__ const vmesh::VelocityBlockContainer Realf Realf ** dev_blockDataOrdered
bool trans_map_1d_amr(const dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, const vector< CellID > &localPropagatedCells, const vector< CellID > &remoteTargetCells, std::vector< uint > &nPencilsLB, const uint dimension, const Realf dt, const uint popID)
void update_remote_mapping_contribution_amr(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, const uint dimension, int direction, const uint popID)
__device__ bool check_skip_blocks(const Realf *__restrict__ const *pencilBlockData, const uint centerOffset)
const uint blockIndexIncrement
const uint pencilBlockDataOffset
static const uint64_t NEIGHBOR_VEL_BLOCK_DATA
static __global__ void __launch_bounds__(WID3, 4) population_scale_kernel(vmesh
const uint64_t INVALID_CELLID
static bool prepareForRebalance
static ARCH_HOSTDEV VecSimple< T > abs(const VecSimple< T > &l)