26#ifndef VLASIATOR_SPATIAL_CELL_GPU_HPP
27#define VLASIATOR_SPATIAL_CELL_GPU_HPP
38#include <unordered_map>
53 #ifndef DEBUG_SPATIAL_CELL
54 #define DEBUG_SPATIAL_CELL
65 vmesh->device_setNewSize(nBlocks);
70 vmesh::LocalID nBlocks,
72 vmesh::VelocityBlockContainer *blockContainer,
75 const int blocki = blockIdx.x;
76 const int i = threadIdx.x;
77 const int j = threadIdx.y;
78 const int k = threadIdx.z;
81 const uint blockLID = blocki;
83 Realf* data = blockContainer->getData(blockLID);
85 data[
ti] = data[
ti] * factor;
92 vmesh::LocalID nBlocks,
94 vmesh::VelocityBlockContainer *blockContainer,
95 vmesh::VelocityMesh *otherVmesh,
96 vmesh::VelocityBlockContainer *otherBlockContainer,
103 const int i = threadIdx.x;
104 const int j = threadIdx.y;
105 const int k = threadIdx.z;
114 const Realf* fromData = otherBlockContainer->getData(incLID);
119 #ifdef USE_WARPACCESSORS
124 if (toLID ==
vmesh->invalidLocalID()) {
125 #ifdef USE_WARPACCESSORS
126 bool created =
vmesh->warpPush_back(GID,
ti);
128 __shared__
bool created;
130 created =
vmesh->push_back(GID);
137 assert(0 &&
"Error in incrementing blockContainer in population_increment_kernel!");
139 toLID = blockContainer->push_back();
140 Real* parameters = blockContainer->getParameters(toLID);
146 Realf* toData = blockContainer->getData(writeLID);
149 toData[
ti] = fromData[
ti] * factor;
153 Realf* toData = blockContainer->getData(toLID);
154 toData[
ti] += fromData[
ti] * factor;
161 vmesh::VelocityMesh *vmesh,
162 vmesh::VelocityBlockContainer *blockContainer,
163 vmesh::VelocityMesh *otherVmesh,
164 vmesh::VelocityBlockContainer *otherBlockContainer
168 const int i = threadIdx.x;
169 const int j = threadIdx.y;
170 const int k = threadIdx.z;
174 size_t newSize = otherVmesh->size();
175 #ifdef DEBUG_SPATIAL_CELL
177 if (blockContainer->size() != newSize) {
178 printf(
"Incorrect VBC size in population replace kernel!\n");
179 blockContainer->setNewSize(newSize);
182 printf(
"Incorrect vmesh size in population replace kernel!\n");
191 #ifdef USE_WARPACCESSORS
200 const Realf* fromData = otherBlockContainer->getData(LID);
201 Realf* toData = blockContainer->getData(LID);
202 toData[
ti] = fromData[
ti];
204 const Real* fromParameters = otherBlockContainer->getParameters(LID);
205 Real* toParameters = blockContainer->getParameters(LID);
207 toParameters[
ti] = fromParameters[
ti];
220 const int ti = threadIdx.x;
226 vmesh->device_setNewSize(newSize);
231 Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID> *globalToLocalMap =
vmesh->gpu_expose_map();
232 Hashinator::Info *info = globalToLocalMap->expose_mapinfo<
false>();
237 const size_t len = globalToLocalMap->bucket_count();
238 const vmesh::GlobalID emptybucket = globalToLocalMap->get_emptybucket();
239 Hashinator::hash_pair<vmesh::GlobalID, vmesh::LocalID>* dst = globalToLocalMap->expose_bucketdata<
false>();
241 if (dst[
i].first != emptybucket) {
242 dst[
i].first = emptybucket;
275 float mlp_error = {std::numeric_limits<float>::max()};
306 for (uint
i=0;
i<2; ++
i) {
309 for (uint
i=0;
i<3; ++
i) {
312 for (uint
i=0;
i<6;
i++) {
350 for (uint
i=0;
i<2; ++
i) {
353 for (uint
i=0;
i<3; ++
i) {
355 V_R[
i] = other.V_R[
i];
356 V_V[
i] = other.V_V[
i];
358 for (uint
i=0;
i<6;
i++) {
360 P_R[
i] = other.P_R[
i];
361 P_V[
i] = other.P_V[
i];
363 vmesh->updateCachedSize();
365 vmesh->updateCachedCapacity();
375 population_replace_kernel<<<newSize, block, 0, stream>>> (
384 #ifdef DEBUG_SPATIAL_CELL
396 for (uint
i=0;
i<2; ++
i) {
399 for (uint
i=0;
i<3; ++
i) {
401 V_R[
i] = other.V_R[
i];
402 V_V[
i] = other.V_V[
i];
404 for (uint
i=0;
i<6;
i++) {
406 P_R[
i] = other.P_R[
i];
407 P_V[
i] = other.P_V[
i];
424 const bool reallocated1 =
blockContainer->setNewCapacity(newSize);
425 const bool reallocated2 =
vmesh->setNewCapacity(newSize);
427 if (reallocated1 || reallocated2) {
440 vmesh->setNewCachedSize(newSize);
449 for (uint
i=0;
i<3; ++
i) {
459 population_scale_kernel<<<nBlocks, block, 0, stream>>> (
480 vmesh->setNewCapacity(nExistingBlocks + nBlocks + 1);
490 population_increment_kernel<<<1, block, 0, stream>>> (
501 vmesh->updateCachedSize();
515 const fileReal* gpuInitBuffer,
518 const int blocki = blockIdx.x;
520 const uint
ti = threadIdx.z*blockDim.x*blockDim.y + threadIdx.y*blockDim.x + threadIdx.x;
522 Realf *cellBlockData = blockContainer->
getData(startLID);
523 const uint
index = blocki;
631 bool doDeleteEmptyBlocks=
true);
634 template <
typename fileReal>
void add_velocity_blocks(
const uint popID,
const std::vector<vmesh::GlobalID>& blocks,fileReal* initBuffer);
639 void clear(
const uint popID,
bool shrink=
false);
647 size_t size(
const uint popID)
const;
665 const bool receiving,
const int neighborhood);
674 std::array<Real, vderivatives::N_V_DERIVATIVES>
derivativesV;
677 std::array<Real, CellParams::N_SPATIAL_CELL_PARAMS>
parameters;
721 #ifdef DEBUG_SPATIAL_CELL
723 std::cerr <<
"ERROR, popID " << popID <<
" exceeds populations.size() " <<
populations.size() <<
" in ";
724 std::cerr << __FILE__ <<
":" << __LINE__ << std::endl;
731 #ifdef DEBUG_SPATIAL_CELL
732 if (blockLID >=
populations[popID].blockContainer->size()) {
733 std::cerr <<
"ERROR, block LID out of bounds, blockContainer->size() " <<
populations[popID].blockContainer->size() <<
" in ";
734 std::cerr << __FILE__ <<
":" << __LINE__ << std::endl;
742 return populations[popID].blockContainer->getData();
747 return populations[popID].blockContainer->getData();
765 return populations[popID].blockContainer->getData(blockLID);
773 return populations[popID].blockContainer->getData(blockLID);
778 return populations[popID].blockContainer->getParameters();
783 return populations[popID].blockContainer->getParameters();
802 return populations[popID].blockContainer->getParameters(blockLID);
807 return populations[popID].blockContainer->getParameters(blockLID);
895 populations[popID].vmesh->getBlockCoordinates(globalID,coords);
903 populations[popID].vmesh->getIndices(block,indices[0],indices[1],indices[2]);
911 return populations[popID].vmesh->getGlobalID(indices[0],indices[1],indices[2]);
915 return populations[popID].vmesh->getGlobalID(blockIndices[0],blockIndices[1],blockIndices[2]);
924 return populations[popID].vmesh->getGlobalID(coords);
928 return populations[popID].vmesh->getGlobalID(coords);
933 return populations[popID].vmesh->getGlobalID(blockLID);
938 return populations[popID].vmesh->getLocalID(blockGID);
950 populations[popID].vmesh->getBlockCoordinates(block,coords);
959 populations[popID].vmesh->getBlockCoordinates(block,coords);
971 populations[popID].vmesh->getBlockCoordinates(block,coords);
980 populations[popID].vmesh->getBlockCoordinates(block,coords);
992 populations[popID].vmesh->getBlockCoordinates(block,coords);
1001 populations[popID].vmesh->getBlockCoordinates(block,coords);
1041 const bool reupload =
populations[popID].vmesh->setNewCapacity(nBlocks);
1042 populations[popID].vmesh->setNewCachedSize(nBlocks);
1087 if (vmeshSize != vbcSize) {
1088 printf(
"checkMesh ERROR: population vmesh %zu and blockcontainer %zu sizes do not match!\n",vmeshSize,vbcSize);
1096 if (vmeshSize != vbcSize) {
1097 printf(
"checkSizes ERROR: population vmesh %zu and blockcontainer %zu sizes do not match!\n",vmeshSize,vbcSize);
1136 size +=
list_delete->size() *
sizeof(Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>);
1137 size +=
list_to_replace->size() *
sizeof(Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>);
1142 size += 2 *
sizeof(Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>);
1143 size +=
sizeof(split::SplitVector<vmesh::GlobalID>);
1144 size += 3 *
sizeof(split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>);
1146 for (
size_t popID=0; popID<
populations.size(); ++popID) {
1149 size +=
sizeof(vmesh::VelocityMesh);
1150 size +=
sizeof(vmesh::VelocityBlockContainer);
1160 uint64_t capacity = 0;
1171 capacity += pow(2,
vbwcl_sizePower) *
sizeof(Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>);
1172 capacity += pow(2,
vbwncl_sizePower) *
sizeof(Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>);
1174 capacity +=
list_delete_capacity *
sizeof(Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>);
1181 capacity += 2 *
sizeof(Hashinator::Hashmap<vmesh::GlobalID,vmesh::LocalID>);
1182 capacity +=
sizeof(split::SplitVector<vmesh::GlobalID>);
1183 capacity += 3 *
sizeof(split::SplitVector<Hashinator::hash_pair<vmesh::GlobalID,vmesh::LocalID>>);
1185 for (
size_t popID=0; popID<
populations.size(); ++popID) {
1186 capacity +=
populations[popID].vmesh->capacityInBytes();
1187 capacity +=
populations[popID].blockContainer->capacityInBytes();
1188 capacity +=
sizeof(vmesh::VelocityMesh);
1189 capacity +=
sizeof(vmesh::VelocityBlockContainer);
1220 std::cerr <<
"Error in adding from buffer: Vmesh not empty!" << __FILE__ <<
' ' << __LINE__ << std::endl;
1224 const uint nBlocks = blocks.size();
1228 populations[popID].blockContainer->setNewCachedSize(0);
1237 if (adds != nBlocks) {
1238 std::cerr <<
"Failed to add blocks" << __FILE__ <<
' ' << __LINE__ << std::endl; exit(1);
1275 #ifdef DEBUG_SPATIAL_CELL
1277 std::cerr <<
"size mismatch in " << __FILE__ <<
' ' << __LINE__ << std::endl;
1278 std::cerr <<
" velocity mesh size "<<
populations[popID].vmesh->size();
1279 std::cerr <<
" VBC size "<<
populations[popID].blockContainer->size();
1280 std::cerr <<
" nBlocks "<<nBlocks;
1281 std::cerr <<
" adds " << adds << std::endl;
1285 #ifdef DEBUG_VLASIATOR
1287 std::cerr <<
"vmesh check error in " << __FILE__ <<
' ' << __LINE__ << std::endl;
1288 std::cerr <<
" velocity mesh size "<<
populations[popID].vmesh->size();
1289 std::cerr <<
" VBC size "<<
populations[popID].blockContainer->size();
1290 std::cerr <<
" nBlocks "<<nBlocks;
1291 std::cerr <<
" adds " << adds << std::endl;
#define gpuPeekAtLastError
#define gpuStreamSynchronize
#define gpuMemcpyHostToDevice
Real * get_block_parameters(const vmesh::LocalID &blockLID, const uint popID)
const vmesh::GlobalID * get_velocity_grid(const uint popID)
bool checkMesh(const uint popID)
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)
uint64_t get_cell_memory_size()
const Realf * get_data(const uint popID) const
void set_population(const Population &pop, cuint popID)
const Real * get_velocity_grid_cell_size(const uint popID)
Real get_velocity_block_vx_min(const uint popID, const vmesh::GlobalID block) const
Real * get_block_parameters(const uint popID)
const Real * get_block_parameters(const vmesh::LocalID &blockLID, const uint popID) const
vmesh::VelocityMesh * get_velocity_mesh(const size_t &popID)
void scale_population(creal factor, cuint popID)
vmesh::LocalID list_delete_capacity
const Population & get_population(const uint popID) const
vmesh::GlobalID get_velocity_block_global_id(const vmesh::LocalID &blockLID, const uint popID) const
vmesh::VelocityBlockContainer * get_velocity_blocks(const size_t &popID)
bool checkSizes(const uint popID)
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)
vmesh::GlobalID get_velocity_block(const uint popID, const Real vx, const Real vy, const Real vz) const
size_t count(const vmesh::GlobalID &block, const uint popID) const
static vmesh::GlobalID invalid_global_id()
void setNewSizeClear(const uint popID)
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
static vmesh::LocalID invalid_local_id()
const std::vector< Population > & get_populations() const
std::array< Realf *, MAX_NEIGHBORS_PER_DIM > neighbor_block_data
static void set_mpi_transfer_direction(const int dimension)
Realf * dev_get_data(const uint popID)
void increment_population(const Population &pop, creal factor, cuint popID)
Realf * get_data(const vmesh::LocalID &blockLID, const uint popID)
void dev_upload_population(const uint popID)
split::SplitVector< vmesh::GlobalID > * list_with_replace_new
void set_mpi_transfer_enabled(bool transferEnabled)
static unsigned int invalid_block_index()
void set_max_r_dt(const uint popID, const Real &value)
vmesh::GlobalID get_velocity_block(const uint popID, const Real *coords) const
void adjustSingleCellVelocityBlocks(const uint popID, bool doDeleteEmpty=false)
vmesh::LocalID get_velocity_block_local_id(const vmesh::GlobalID &blockGID, const uint popID) const
vmesh::LocalID getReservation(const uint popID) const
void debug_population_check(const uint popID, const vmesh::LocalID blockLID) const
static bool mpiTransferAtSysBoundaries
Real getVelocityBlockMinValue(const uint popID) const
Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > * dev_velocity_block_with_content_map
Real get_velocity_block_vz_min(const uint popID, const vmesh::GlobalID block) const
void increment_mass_loss(cuint popID, Real increment)
static bool setCommunicatedSpecies(const uint popID)
Real get_velocity_block_vz_max(const uint popID, const vmesh::GlobalID block) const
void clear(const uint popID, bool shrink=false)
split::SplitVector< Hashinator::hash_pair< vmesh::GlobalID, vmesh::LocalID > > * list_with_replace_old
static unsigned int invalid_block_index()
void prepare_to_receive_blocks(const uint popID)
Real get_velocity_block_vy_min(const uint popID, const vmesh::GlobalID block) const
uint64_t get_cell_memory_capacity()
std::vector< vmesh::GlobalID > * velocity_block_with_content_list
std::array< Real, vderivatives::N_V_DERIVATIVES > derivativesV
split::SplitVector< Hashinator::hash_pair< vmesh::GlobalID, vmesh::LocalID > > * dev_list_to_replace
static uint64_t get_mpi_transfer_type(void)
const Real * get_cell_parameters() const
void add_velocity_blocks(const uint popID, const std::vector< vmesh::GlobalID > &blocks, fileReal *initBuffer)
Real get_velocity_block_vy_max(const uint popID, const vmesh::GlobalID block) const
velocity_block_indices_t get_velocity_block_indices(const uint popID, const vmesh::GlobalID globalID)
split::SplitVector< vmesh::GlobalID > * dev_list_with_replace_new
vmesh::LocalID velocity_block_with_content_list_capacity
void add_velocity_blocks(const uint popID, const std::vector< vmesh::GlobalID > &blocks, fileReal *avgBuffer)
void dev_resize_vmesh(const uint popID, const uint nBlocks)
std::array< Realf, WID3 > null_block_data
vmesh::LocalID list_to_replace_capacity
void get_velocity_block_size(const uint popID, const vmesh::GlobalID block, Real size[3])
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
vmesh::LocalID get_number_of_all_velocity_blocks() const
Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > * velocity_block_with_no_content_map
vmesh::LocalID list_with_replace_new_capacity
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
std::vector< Population > & get_populations()
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
const vmesh::LocalID * get_velocity_grid_length(const uint popID)
split::SplitVector< Hashinator::hash_pair< vmesh::GlobalID, vmesh::LocalID > > * dev_list_with_replace_old
Real * get_cell_parameters()
Realf * get_data(const uint popID)
const Real & get_max_v_dt(const uint popID) const
Population & get_population(const uint popID)
vmesh::LocalID list_with_replace_old_capacity
vmesh::GlobalID find_velocity_block(vmesh::GlobalID cellIndices[3], const uint popID)
vmesh::LocalID velocity_block_with_content_list_size
void get_velocity_block_coordinates(const uint popID, const vmesh::GlobalID &globalID, Real *coords)
SpatialCell(const SpatialCell &other)
const Real * get_block_parameters(const uint popID) const
Real get_velocity_block_vx_max(const uint popID, const vmesh::GlobalID block) const
void update_velocity_block_content_lists(const uint popID)
static void set_mpi_transfer_type(const uint64_t type, bool atSysBoundaries=false)
std::array< Real, CellParams::N_SPATIAL_CELL_PARAMS > parameters
const SpatialCell & operator=(const SpatialCell &other)
const vmesh::VelocityBlockContainer * get_velocity_blocks(const size_t &popID) const
split::SplitVector< Hashinator::hash_pair< vmesh::GlobalID, vmesh::LocalID > > * list_to_replace
static uint64_t mpi_transfer_type
const Realf * get_data(const vmesh::LocalID &blockLID, const uint popID) const
void setReservation(const uint popID, const vmesh::LocalID reservationsize, bool force=false)
Hashinator::Hashmap< vmesh::GlobalID, vmesh::LocalID > * velocity_block_with_content_map
static uint64_t get_mpi_transfer_type(void)
Real * dev_get_block_parameters(const uint popID)
vmesh::VelocityBlockContainer * dev_get_velocity_blocks(const size_t &popID)
int get_number_of_populations() const
std::vector< spatial_cell::Population > populations
vmesh::GlobalID get_velocity_block(const uint popID, vmesh::GlobalID blockIndices[3]) const
vmesh::GlobalID get_velocity_block(const uint popID, const velocity_block_indices_t indices) const
static vmesh::GlobalID invalid_global_id()
static vmesh::LocalID invalid_local_id()
vmesh::VelocityMesh * dev_get_velocity_mesh(const size_t &popID)
std::map< int, std::set< int > > face_neighbor_ranks
bool add_velocity_block(const vmesh::GlobalID &block, const uint popID)
Realf * gpu_rhoLossAdjust
const Real * get_velocity_grid_block_size(const uint popID)
ARCH_HOSTDEV Real * getParameters()
ARCH_HOSTDEV Realf * getData()
ARCH_HOSTDEV bool setNewSize(const vmesh::LocalID newSize)
ARCH_DEV void placeBlock(const vmesh::GlobalID GID, const vmesh::LocalID LID)
static vmesh::LocalID invalidBlockIndex()
static vmesh::LocalID invalidLocalID()
ARCH_DEV void device_setNewSize(const vmesh::LocalID newSize)
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
void getBlockInfo(const vmesh::GlobalID &globalID, Real *array) const
const vmesh::VelocityMesh *__restrict__ vmesh
GPUMemoryManager gpuMemoryManager
__host__ gpuStream_t gpu_getStream()
__host__ uint gpu_getThread()
static const double BLOCK_ALLOCATION_PADDING
#define SUBPOINTER_ALLOCATE_ASYNC(object, member, index, bytes, stream)
#define GET_POINTER(object, type, member)
dev_velocityBlockContainer[cellIdx] getData()[velocityIdx *WID3+k *WID2+j *WID+i]
@ N_VELOCITY_BLOCK_PARAMS
std::array< vmesh::LocalID, 3 > velocity_block_indices_t
static __global__ void resize_and_empty_kernel(vmesh::VelocityMesh *vmesh, vmesh::VelocityBlockContainer *blockContainer, vmesh::LocalID newSize)
__global__ void add_blocks_from_buffer_kernel(const vmesh::VelocityMesh *vmesh, vmesh::VelocityBlockContainer *blockContainer, const vmesh::LocalID startLID, const vmesh::GlobalID *gpuInitBlocks, const fileReal *gpuInitBuffer, const uint nBlocks)
static __global__ void __launch_bounds__(WID3, 4) population_scale_kernel(vmesh
std::array< unsigned int, 3 > velocity_cell_indices_t
static __global__ void resize_vmesh_ondevice_kernel(vmesh::VelocityMesh *vmesh, vmesh::LocalID nBlocks)
T * getPointer(const size_t &pointerIndex) const
vmesh::LocalID reservation
Real velocityBlockMinValue
vmesh::VelocityBlockContainer * blockContainer
size_t dev_blockContainer
std::vector< char > compressed_state_buffer
void ResizeClear(const uint newSize)
const Population & operator=(const Population &other)
void Increment(const Population &other, creal factor)
Population(const Population &other)