23#include <unordered_set>
48 for (
unsigned int i=0;
i<
WID3; ++
i) {
74 for (uint popID=0; popID<
populations.size(); ++popID) {
78 populations[popID].blockContainer->gpu_prefetchDevice();
87 void *buf0 = malloc(
sizeof(split::SplitVector<vmesh::GlobalID>));
98 void *buf1 = malloc(
sizeof(Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>));
99 void *buf2 = malloc(
sizeof(Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>));
108 void *buf11 = malloc(
sizeof(split::SplitVector<vmesh::GlobalID>));
109 void *buf12 = malloc(
sizeof(split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>));
110 void *buf13 = malloc(
sizeof(split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>));
111 void *buf14 = malloc(
sizeof(split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>));
171 std::cerr<<
"Warning! Spatial Cell GPU copy constructor called. Performance may degrade."<<std::endl;
176 void *buf0 = malloc(
sizeof(split::SplitVector<vmesh::GlobalID>));
185 void *buf1 = malloc(
sizeof(Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>));
186 void *buf2 = malloc(
sizeof(Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>));
195 void *buf11 = malloc(
sizeof(split::SplitVector<vmesh::GlobalID>));
196 void *buf12 = malloc(
sizeof(split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>));
197 void *buf13 = malloc(
sizeof(split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>));
198 void *buf14 = malloc(
sizeof(split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>));
229 for (
unsigned int i=0;
i<
WID3; ++
i) {
262 void *buf1 = malloc(
sizeof(Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>));
271 void *buf2 = malloc(
sizeof(Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>));
309 for (
unsigned int i=0;
i<
WID3; ++
i) {
325 if (force || (reservationsize >
populations[popID].reservation)) {
335 const size_t reserveSize =
populations[popID].reservation;
451 std::cerr<<
"Warning! "<<__FILE__<<
":"<<__LINE__<<
" Halo extent is not 1, unsupported size."<<std::endl;
549 auto rule_add = [emptybucket, tombstone, invalidGID, invalidLID]
550 __device__(
const Hashinator::hash_pair<vmesh::GlobalID, vmesh::LocalID>& kval) ->
bool {
551 return kval.first != emptybucket &&
552 kval.first != tombstone &&
553 kval.first != invalidGID &&
556 kval.second == invalidLID; };
559 if (doDeleteEmptyBlocks) {
563 auto rule_delete_move = [emptybucket, tombstone, vbwncm, d_list_add, dev_vmesh, invalidGID, invalidLID]
564 __device__(
const Hashinator::hash_pair<vmesh::GlobalID, vmesh::LocalID>& kval) ->
bool {
566 + d_list_add->size() - vbwncm->size();
567 return kval.first != emptybucket &&
568 kval.first != tombstone &&
569 kval.first != invalidGID &&
570 kval.second >= nBlocksAfterAdjust1 &&
571 kval.second != invalidLID; };
572 auto rule_to_replace = [emptybucket, tombstone, vbwncm, d_list_add, dev_vmesh, invalidGID, invalidLID]
573 __device__(
const Hashinator::hash_pair<vmesh::GlobalID, vmesh::LocalID>& kval) ->
bool {
575 + d_list_add->size() - vbwncm->size();
576 return kval.first != emptybucket &&
577 kval.first != tombstone &&
578 kval.first != invalidGID &&
579 kval.second < nBlocksAfterAdjust2 &&
580 kval.second != invalidGID; };
596 populations[popID].vmesh->gpu_cleanHashMap(stream);
599 #ifdef DEBUG_SPATIAL_CELL
602 if (vmeshSize != vbcSize) {
603 printf(
"ERROR: population vmesh %zu and blockcontainer %zu sizes do not match!\n",vmeshSize,vbcSize);
606 #ifdef DEBUG_VLASIATOR
609 printf(
"ERROR in vmesh check: %s at %d\n",__FILE__,__LINE__);
634 CHK_ERR(
gpuMemcpyAsync(
GET_SUBPOINTER(
gpuMemoryManager,
vmesh::LocalID, host_returnLID, cpuThreadID),
GET_SUBPOINTER(
gpuMemoryManager,
vmesh::LocalID, returnLID, cpuThreadID), 4*
sizeof(
vmesh::LocalID),
gpuMemcpyDeviceToHost, stream) );
641 if ( (nBlocksAfterAdjust > nBlocksBeforeAdjust) && (resizeDevSuccess == 0)) {
644 populations[popID].vmesh->setNewSize(nBlocksAfterAdjust);
646 populations[popID].blockContainer->setNewSize(nBlocksAfterAdjust);
650 if (nBlocksToChange==0) {
651 return nBlocksAfterAdjust;
657 const uint vlasiBlocksPerWorkUnit = 1;
659 const uint launchBlocks = 1 + ((nBlocksToChange - 1) / vlasiBlocksPerWorkUnit);
664 update_velocity_blocks_kernel<<<launchBlocks, vlasiBlocksPerWorkUnit * WID3, 0, stream>>> (
677 CHK_ERR(
gpuMemcpyAsync(
GET_SUBPOINTER(
gpuMemoryManager,
Realf, host_returnRealf, cpuThreadID),
GET_SUBPOINTER(
gpuMemoryManager,
Realf, returnRealf, cpuThreadID),
sizeof(
Realf),
gpuMemcpyDeviceToHost, stream) );
680 if (nBlocksAfterAdjust < nBlocksBeforeAdjust) {
690 populations[popID].vmesh->setNewCachedSize(nBlocksAfterAdjust);
691 populations[popID].blockContainer->setNewCachedSize(nBlocksAfterAdjust);
697 #ifdef DEBUG_SPATIAL_CELL
699 if (nAll!=nBlocksAfterAdjust) {
702 printf(
"after kernel, size is %d should be %d\n",nAll,nBlocksAfterAdjust);
706 printf(
"LID %d GID-solved %d LID-solved %d\n",m,GIDs,LIDs);
711 return nBlocksAfterAdjust;
734 const uint nBlocks =
populations[popID].vmesh->size();
743 const uint vlasiBlocksPerWorkUnit = 1;
745 const uint launchBlocks = 1 + ((nBlocks - 1) / vlasiBlocksPerWorkUnit);
750 update_velocity_block_content_lists_kernel<<<launchBlocks, (vlasiBlocksPerWorkUnit *
WID3), 0, stream>>> (
755 velocity_block_min_value
761 split::SplitInfo info;
770 populations[p].blockContainer->gpu_prefetchDevice();
805 const int sender_rank,
806 const int receiver_rank,
807 const bool receiving,
808 const int neighborhood
811 std::vector<MPI_Aint> displacements;
812 std::vector<int> block_lengths;
845 displacements.push_back(0);
846 block_lengths.push_back(0);
903 displacements.push_back((uint8_t*) &(this->
parameters[0]) - (uint8_t*)
this);
910 block_lengths.push_back(
sizeof(
Real) * 6);
916 block_lengths.push_back(
sizeof(
Real) * 6);
922 block_lengths.push_back(
sizeof(
Real) * 4);
928 block_lengths.push_back(
sizeof(
Real) * 4);
934 block_lengths.push_back(
sizeof(
Real));
940 block_lengths.push_back(
sizeof(
Real));
945 displacements.push_back((uint8_t*) &(this->
derivativesBVOL[0]) - (uint8_t*)
this);
950 displacements.push_back((uint8_t*) &(this->
ioLocalCellId) - (uint8_t*)
this);
951 block_lengths.push_back(
sizeof(uint64_t));
957 block_lengths.push_back(
sizeof(
Real) * 3);
964 block_lengths.push_back(
sizeof(
Real) * 3);
969 block_lengths.push_back(
sizeof(
Real) * 3);
974 displacements.push_back((uint8_t*) &(this->
sysBoundaryFlag) - (uint8_t*)
this);
975 block_lengths.push_back(
sizeof(uint));
976 displacements.push_back((uint8_t*) &(this->
sysBoundaryLayer) - (uint8_t*)
this);
977 block_lengths.push_back(
sizeof(uint));
986 for (uint popID=0; popID<
populations.size(); ++popID) {
987 displacements.push_back((uint8_t*) &(
populations[popID].RHO) - (uint8_t*)
this);
988 block_lengths.push_back(offsetof(spatial_cell::Population, N_blocks));
1000 void* address =
this;
1002 MPI_Datatype datatype;
1004 if (displacements.size() > 0) {
1006 MPI_Type_create_hindexed(
1007 displacements.size(),
1015 datatype = MPI_BYTE;
1018 const bool printMpiDatatype =
false;
1019 if(printMpiDatatype) {
1022 MPI_Type_size(datatype,&mpiSize);
1023 MPI_Comm_rank(MPI_COMM_WORLD,&
myRank);
1024 cout <<
myRank <<
" get_mpi_datatype: " << cellID <<
" " << sender_rank <<
" " << receiver_rank <<
" " << mpiSize <<
", Nblocks = " <<
populations[
activePopID].N_blocks <<
", nbr Nblocks =";
1027 if ( receiving || ranks.find(receiver_rank) != ranks.end()) {
1033 cout <<
" face_neighbor_ranks =";
1035 cout <<
" " << rank;
1040 return std::make_tuple(address,
count,datatype);
1068 #ifdef USE_WARPACCESSORS
1088 #ifdef DEBUG_SPATIAL_CELL
1091 std::cerr << __FILE__ <<
":" << __LINE__ << std::endl;
1123 bool success =
true;
1125 size_t largestAmount = 0;
1126 for (
size_t popID=0; popID<
populations.size(); ++popID) {
1129 *
populations[popID].blockContainer->getBlockAllocationFactor();
1130 largestAmount = std::max(largestAmount,(
size_t)
populations[popID].blockContainer->size());
1132 if (
populations[popID].blockContainer->capacity() > amount ) {
1133 if (
populations[popID].blockContainer->setNewCapacityShrink(amount) ==
false) {
1143 cerr <<
"SC::printMeshSizes:" << endl;
1165 const Real newMinValue =
k*
x+
b;
1171 populations[popID].velocityBlockMinValue = newMinValue;
set(gca, 'YDir', 'normal')
#define gpuPeekAtLastError
#define gpuStreamSynchronize
#define gpuMemcpyDeviceToHost
split::SplitVector< vmesh::GlobalID > * dev_velocity_block_with_content_list
vmesh::LocalID get_number_of_velocity_blocks(const uint popID) const
void debug_population_check(const uint popID) const
void updateSparseMinValue(const uint popID)
Real * get_block_parameters(const uint popID)
vmesh::LocalID list_delete_capacity
vmesh::LocalID vbwncl_sizePower
Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > * dev_velocity_block_with_no_content_map
vmesh::LocalID adjust_velocity_blocks_caller(const uint popID)
size_t count(const vmesh::GlobalID &block, const uint popID) const
std::tuple< void *, int, MPI_Datatype > get_mpi_datatype(const CellID cellID, const int sender_rank, const int receiver_rank, const bool receiving, const int neighborhood)
size_t size(const uint popID) const
std::array< Realf *, MAX_NEIGHBORS_PER_DIM > neighbor_block_data
split::SplitVector< vmesh::GlobalID > * list_with_replace_new
void set_max_r_dt(const uint popID, const Real &value)
void adjustSingleCellVelocityBlocks(const uint popID, bool doDeleteEmpty=false)
vmesh::LocalID getReservation(const uint popID) const
static bool mpiTransferAtSysBoundaries
static bool setCommunicatedSpecies(const uint popID)
Real getVelocityBlockMinValue(const uint popID) const
Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > * dev_velocity_block_with_content_map
split::SplitVector< Hashinator::hash_pair< vmesh::GlobalID, vmesh::LocalID > > * list_with_replace_old
void prepare_to_receive_blocks(const uint popID)
std::vector< vmesh::GlobalID > * velocity_block_with_content_list
split::SplitVector< Hashinator::hash_pair< vmesh::GlobalID, vmesh::LocalID > > * dev_list_to_replace
split::SplitVector< vmesh::GlobalID > * dev_list_with_replace_new
vmesh::LocalID velocity_block_with_content_list_capacity
void dev_resize_vmesh(const uint popID, const uint nBlocks)
std::array< Realf, WID3 > null_block_data
vmesh::LocalID list_to_replace_capacity
void set_max_v_dt(const uint popID, const Real &value)
void setNewSizeClear(const uint popID, const vmesh::LocalID &newSize)
vmesh::LocalID vbwcl_sizePower
const Real & get_max_r_dt(const uint popID) const
split::SplitVector< Hashinator::hash_pair< vmesh::GlobalID, vmesh::LocalID > > * list_delete
Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > * velocity_block_with_no_content_map
vmesh::LocalID list_with_replace_new_capacity
std::array< vmesh::LocalID, MAX_NEIGHBORS_PER_DIM > neighbor_number_of_blocks
void applyReservation(const uint popID)
std::array< Real, bvolderivatives::N_BVOL_DERIVATIVES > derivativesBVOL
void adjust_velocity_blocks(const std::vector< SpatialCell * > &spatial_neighbors, const uint popID, bool doDeleteEmptyBlocks=true)
split::SplitVector< Hashinator::hash_pair< vmesh::GlobalID, vmesh::LocalID > > * dev_list_delete
split::SplitVector< Hashinator::hash_pair< vmesh::GlobalID, vmesh::LocalID > > * dev_list_with_replace_old
Realf * get_data(const uint popID)
const Real & get_max_v_dt(const uint popID) const
vmesh::LocalID list_with_replace_old_capacity
vmesh::LocalID velocity_block_with_content_list_size
void update_velocity_block_content_lists(const uint popID)
std::array< Real, CellParams::N_SPATIAL_CELL_PARAMS > parameters
const SpatialCell & operator=(const SpatialCell &other)
split::SplitVector< Hashinator::hash_pair< vmesh::GlobalID, vmesh::LocalID > > * list_to_replace
static uint64_t mpi_transfer_type
void setReservation(const uint popID, const vmesh::LocalID reservationsize, bool force=false)
Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > * velocity_block_with_content_map
std::vector< spatial_cell::Population > populations
std::map< int, std::set< int > > face_neighbor_ranks
bool add_velocity_block(const vmesh::GlobalID &block, const uint popID)
std::vector< vmesh::GlobalID > * getGrid()
static vmesh::LocalID invalidLocalID()
static vmesh::GlobalID invalidGlobalID()
#define MAX_NEIGHBORS_PER_DIM
const vmesh::VelocityMesh *__restrict__ vmesh
split::SplitVector< vmesh::GlobalID > * list_with_replace_new
GPUMemoryManager gpuMemoryManager
__host__ gpuStream_t gpu_getStream()
uint gpu_largest_columnCount
__host__ uint gpu_getThread()
#define GET_SUBPOINTER(object, type, member, index)
static const uint INIT_MAP_SIZE(16 - WID)
static const double BLOCK_ALLOCATION_PADDING
static const uint INIT_VMESH_SIZE(32768/WID3)
ObjectWrapper & getObjectWrapper()
@ N_VELOCITY_BLOCK_PARAMS
static const uint64_t CELL_GRADPE_TERM
static const uint64_t VEL_BLOCK_PARAMETERS
static const uint64_t CELL_P
static const uint64_t REFINEMENT_PARAMETERS
static const uint64_t CELL_SYSBOUNDARYFLAG
static const uint64_t CELL_BVOL
static const uint64_t CELL_RHOM_V
static const uint64_t CELL_RHOMDT2_VDT2
static const uint64_t POP_METADATA
static const uint64_t VEL_BLOCK_LIST_STAGE2
static const uint64_t CELL_BVOL_DERIVATIVES
static const uint64_t VEL_BLOCK_LIST_STAGE1
static const uint64_t CELL_PDT2
static const uint64_t CELL_IOLOCALCELLID
static const uint64_t VEL_BLOCK_WITH_CONTENT_STAGE1
static const uint64_t VEL_BLOCK_DATA
static const uint64_t CELL_RHOQ
static const uint64_t NEIGHBOR_VEL_BLOCK_DATA
static const uint64_t VEL_BLOCK_WITH_CONTENT_STAGE2
static const uint64_t CELL_PARAMETERS
static const uint64_t CELL_RHOQDT2
static const uint64_t CELL_DIMENSIONS
static const uint acc_reserve_multiplier
__global__ void resize_vbc_kernel_pre(vmesh::VelocityMesh *vmesh, vmesh::VelocityBlockContainer *blockContainer, const split::SplitVector< vmesh::GlobalID > *__restrict__ list_with_replace_new, const split::SplitVector< Hashinator::hash_pair< vmesh::GlobalID, vmesh::LocalID > > *__restrict__ list_delete, const split::SplitVector< Hashinator::hash_pair< vmesh::GlobalID, vmesh::LocalID > > *__restrict__ list_to_replace, const split::SplitVector< Hashinator::hash_pair< vmesh::GlobalID, vmesh::LocalID > > *__restrict__ list_with_replace_old, vmesh::LocalID *returnLID, Realf *gpu_rhoLossAdjust)
__global__ void update_velocity_halo_kernel(const vmesh::VelocityMesh *__restrict__ vmesh, const vmesh::LocalID velocity_block_with_content_list_size, const vmesh::GlobalID *__restrict__ velocity_block_with_content_list_data, Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > *dev_velocity_block_with_content_map, Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > *dev_velocity_block_with_no_content_map)
__global__ void resize_vbc_kernel_post(vmesh::VelocityMesh *vmesh, vmesh::VelocityBlockContainer *blockContainer, const vmesh::LocalID nBlocksAfterAdjust)
__global__ void update_vmesh_and_blockparameters_kernel(vmesh::VelocityMesh *dev_vmesh, vmesh::VelocityBlockContainer *dev_blockContainer, const vmesh::LocalID nLIDs)
T * getPointer(const size_t &pointerIndex) const
std::vector< species::Species > particleSpecies
static int amrMaxSpatialRefLevel
Real sparseDynamicMinValue2
Real sparseDynamicMinValue1
Real sparseDynamicBulkValue2
Real sparseDynamicBulkValue1
int sparseDynamicAlgorithm