forked from fmihpc/vlasiator
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvelocity_mesh_parameters.cpp
129 lines (114 loc) · 5.12 KB
/
velocity_mesh_parameters.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "velocity_mesh_parameters.h"
#include <iostream>
#include <cstdlib>
#ifdef USE_GPU
#include "include/splitvector/splitvec.h"
#include "arch/gpu_base.hpp"
#endif
// Pointers to MeshWrapper objects
static vmesh::MeshWrapper *meshWrapper;
#ifdef USE_GPU
__device__ __constant__ vmesh::MeshWrapper *meshWrapperDev;
__global__ void debug_kernel(
const uint popID
) {
vmesh::printVelocityMesh(0);
}
#endif
void vmesh::allocMeshWrapper() {
// This is now allocated in unified memory
meshWrapper = new vmesh::MeshWrapper();
}
vmesh::MeshWrapper* vmesh::host_getMeshWrapper() {
return meshWrapper;
}
// This needs to be ARCH_HOSTDEV for compilation although it's called only from device side
#ifdef USE_GPU
//#pragma hd_warning_disable // only applies to next function
#pragma nv_diag_suppress=20091
ARCH_HOSTDEV vmesh::MeshWrapper* vmesh::gpu_getMeshWrapper() {
return meshWrapperDev;
}
void vmesh::MeshWrapper::uploadMeshWrapper() {
// Store address to velocityMeshes array
std::array<vmesh::MeshParameters,MAX_VMESH_PARAMETERS_COUNT> * temp = meshWrapper->velocityMeshes;
// gpu-Malloc space on device, copy array contents
std::array<vmesh::MeshParameters,MAX_VMESH_PARAMETERS_COUNT> *velocityMeshes_upload;
CHK_ERR( gpuMalloc((void **)&velocityMeshes_upload, sizeof(std::array<vmesh::MeshParameters,MAX_VMESH_PARAMETERS_COUNT>)) );
CHK_ERR( gpuMemcpy(velocityMeshes_upload, meshWrapper->velocityMeshes, sizeof(std::array<vmesh::MeshParameters,MAX_VMESH_PARAMETERS_COUNT>),gpuMemcpyHostToDevice) );
// Make wrapper point to device-side array
meshWrapper->velocityMeshes = velocityMeshes_upload;
// Allocate and copy meshwrapper on device
vmesh::MeshWrapper* MWdev;
CHK_ERR( gpuMalloc((void **)&MWdev, sizeof(vmesh::MeshWrapper)) );
CHK_ERR( gpuMemcpy(MWdev, meshWrapper, sizeof(vmesh::MeshWrapper),gpuMemcpyHostToDevice) );
// Set the global symbol of meshWrapper
CHK_ERR( gpuMemcpyToSymbol(meshWrapperDev, &MWdev, sizeof(vmesh::MeshWrapper*)) );
// Copy host-side address back
meshWrapper->velocityMeshes = temp;
// And sync
CHK_ERR( gpuDeviceSynchronize() );
}
#endif
void vmesh::MeshWrapper::initVelocityMeshes(const uint nMeshes) {
// Verify lengths match?
if (meshWrapper->velocityMeshesCreation->size() != nMeshes) {
printf("Warning! Initializing only %d velocity meshes out of %d created ones.\n",nMeshes,
(int)meshWrapper->velocityMeshesCreation->size());
}
// Create pointer to array of sufficient length
meshWrapper->velocityMeshes = new std::array<vmesh::MeshParameters,MAX_VMESH_PARAMETERS_COUNT>;
// Copy data in, also set auxiliary values
for (uint i=0; i<nMeshes; ++i) {
vmesh::MeshParameters* vMesh = &(meshWrapper->velocityMeshes->at(i));
vmesh::MeshParameters* vMeshIn = &(meshWrapper->velocityMeshesCreation->at(i));
vMesh->refLevelMaxAllowed = vMeshIn->refLevelMaxAllowed;
// Limits
vMesh->meshLimits[0] = vMeshIn->meshLimits[0];
vMesh->meshLimits[1] = vMeshIn->meshLimits[1];
vMesh->meshLimits[2] = vMeshIn->meshLimits[2];
vMesh->meshLimits[3] = vMeshIn->meshLimits[3];
vMesh->meshLimits[4] = vMeshIn->meshLimits[4];
vMesh->meshLimits[5] = vMeshIn->meshLimits[5];
// Grid length
vMesh->gridLength[0] = vMeshIn->gridLength[0];
vMesh->gridLength[1] = vMeshIn->gridLength[1];
vMesh->gridLength[2] = vMeshIn->gridLength[2];
// Block length
vMesh->blockLength[0] = vMeshIn->blockLength[0];
vMesh->blockLength[1] = vMeshIn->blockLength[1];
vMesh->blockLength[2] = vMeshIn->blockLength[2];
// Calculate derived mesh parameters:
vMesh->meshMinLimits[0] = vMesh->meshLimits[0];
vMesh->meshMinLimits[1] = vMesh->meshLimits[2];
vMesh->meshMinLimits[2] = vMesh->meshLimits[4];
vMesh->meshMaxLimits[0] = vMesh->meshLimits[1];
vMesh->meshMaxLimits[1] = vMesh->meshLimits[3];
vMesh->meshMaxLimits[2] = vMesh->meshLimits[5];
vMesh->gridSize[0] = vMesh->meshMaxLimits[0] - vMesh->meshMinLimits[0];
vMesh->gridSize[1] = vMesh->meshMaxLimits[1] - vMesh->meshMinLimits[1];
vMesh->gridSize[2] = vMesh->meshMaxLimits[2] - vMesh->meshMinLimits[2];
vMesh->blockSize[0] = vMesh->gridSize[0] / vMesh->gridLength[0];
vMesh->blockSize[1] = vMesh->gridSize[1] / vMesh->gridLength[1];
vMesh->blockSize[2] = vMesh->gridSize[2] / vMesh->gridLength[2];
vMesh->cellSize[0] = vMesh->blockSize[0] / vMesh->blockLength[0];
vMesh->cellSize[1] = vMesh->blockSize[1] / vMesh->blockLength[1];
vMesh->cellSize[2] = vMesh->blockSize[2] / vMesh->blockLength[2];
vMesh->max_velocity_blocks
= vMeshIn->gridLength[0]
* vMeshIn->gridLength[1]
* vMeshIn->gridLength[2];
vMesh->initialized = true;
}
#ifdef USE_GPU
// Now all velocity meshes have been initialized on host, into
// the array. Now we need to upload a copy onto GPU.
vmesh::MeshWrapper::uploadMeshWrapper();
// printf("Host printout\n");
// vmesh::printVelocityMesh(0);
// printf("Device printout\n");
// debug_kernel<<<1, 1, 0, 0>>> (0);
// CHK_ERR( gpuDeviceSynchronize() );
#endif
return;
}