Refactoring

This commit is contained in:
André R. Brodtkorb
2018-10-30 15:14:19 +01:00
parent 10d8e26108
commit e434b4e02a
20 changed files with 325 additions and 278 deletions

View File

@@ -48,6 +48,10 @@ inline __device__ __host__ float clamp(const float f, const float a, const float
return fmaxf(a, fminf(f, b));
}
inline __device__ __host__ int clamp(const int f, const int a, const int b) {
return (f < b) ? ( (f > a) ? f : a) : b;
}
@@ -60,37 +64,27 @@ __device__ float desingularize(float x_, float eps_) {
/**
* Reads a block of data with ghost cells
*/
template<int vars, int sm_width, int sm_height, int block_width, int block_height>
inline __device__ void readBlock(float* ptr_[vars], int pitch_[vars],
float shmem[vars][sm_height][sm_width],
template<int block_width, int block_height, int ghost_cells>
inline __device__ void readBlock(float* ptr_, int pitch_,
float shmem[block_height+2*ghost_cells][block_width+2*ghost_cells],
const int max_x_, const int max_y_) {
//Index of block within domain
const int bx = blockDim.x * blockIdx.x;
const int by = blockDim.y * blockIdx.y;
float* rows[3];
//Read into shared memory
for (int j=threadIdx.y; j<sm_height; j+=block_height) {
const int l = clamp(by + j, 0, max_y_-1); // Clamp out of bounds
//Loop over all variables
for (int j=threadIdx.y; j<block_height+2*ghost_cells; j+=block_height) {
const int l = min(by + j, max_y_-1);
float* row = (float*) ((char*) ptr_ + pitch_*l);
//Compute the pointer to current row in the arrays
for (int m=0; m<vars; ++m) {
rows[m] = (float*) ((char*) ptr_[m] + pitch_[m]*l);
}
for (int i=threadIdx.x; i<sm_width; i+=block_width) {
const int k = clamp(bx + i, 0, max_x_-1); // Clamp out of bounds
for (int m=0; m<vars; ++m) {
shmem[m][j][i] = rows[m][k];
}
for (int i=threadIdx.x; i<block_width+2*ghost_cells; i+=block_width) {
const int k = min(bx + i, max_x_-1);
shmem[j][i] = row[k];
}
}
}
@@ -98,24 +92,23 @@ inline __device__ void readBlock(float* ptr_[vars], int pitch_[vars],
/**
* Writes a block of data to global memory for the shallow water equations.
*/
template<int sm_width, int sm_height, int offset_x=0, int offset_y=0>
template<int block_width, int block_height, int ghost_cells>
inline __device__ void writeBlock(float* ptr_, int pitch_,
float shmem[sm_height][sm_width],
float shmem[block_height+2*ghost_cells][block_width+2*ghost_cells],
const int width, const int height) {
//Index of cell within domain
const int ti = blockDim.x*blockIdx.x + threadIdx.x + offset_x;
const int tj = blockDim.y*blockIdx.y + threadIdx.y + offset_y;
const int ti = blockDim.x*blockIdx.x + threadIdx.x + ghost_cells;
const int tj = blockDim.y*blockIdx.y + threadIdx.y + ghost_cells;
//Only write internal cells
if (ti < width+offset_x && tj < height+offset_y) {
if (ti < width+ghost_cells && tj < height+ghost_cells) {
//Index of thread within block
const int tx = threadIdx.x + offset_x;
const int ty = threadIdx.y + offset_y;
const int tx = threadIdx.x + ghost_cells;
const int ty = threadIdx.y + ghost_cells;
float* const row = (float*) ((char*) ptr_ + pitch_*tj);
row[ti] = shmem[ty][tx];
@@ -129,60 +122,93 @@ inline __device__ void writeBlock(float* ptr_, int pitch_,
/**
* Writes a block of data to global memory for the shallow water equations.
*/
__device__ void writeBlock2(float* h_ptr_, int h_pitch_,
float* hu_ptr_, int hu_pitch_,
float* hv_ptr_, int hv_pitch_,
float Q[3][BLOCK_HEIGHT+4][BLOCK_WIDTH+4],
const int nx_, const int ny_) {
writeBlock<BLOCK_WIDTH+4, BLOCK_HEIGHT+4, 2, 2>( h_ptr_, h_pitch_, Q[0], nx_, ny_);
writeBlock<BLOCK_WIDTH+4, BLOCK_HEIGHT+4, 2, 2>(hu_ptr_, hu_pitch_, Q[1], nx_, ny_);
writeBlock<BLOCK_WIDTH+4, BLOCK_HEIGHT+4, 2, 2>(hv_ptr_, hv_pitch_, Q[2], nx_, ny_);
}
/**
* No flow boundary conditions for the shallow water equations
* with one ghost cell in each direction
*/
__device__ void noFlowBoundary1(float Q[3][BLOCK_HEIGHT+2][BLOCK_WIDTH+2], const int nx_, const int ny_) {
//Global index
const int ti = blockDim.x*blockIdx.x + threadIdx.x + 1; //Skip global ghost cells, i.e., +1
const int tj = blockDim.y*blockIdx.y + threadIdx.y + 1;
template<int block_width, int block_height, int ghost_cells, int scale_east_west=1, int scale_north_south=1>
__device__ void noFlowBoundary(float Q[block_height+2*ghost_cells][block_width+2*ghost_cells], const int nx_, const int ny_) {
const int ti = blockDim.x*blockIdx.x + threadIdx.x + ghost_cells;
const int tj = blockDim.y*blockIdx.y + threadIdx.y + ghost_cells;
//Block-local indices
const int tx = threadIdx.x;
const int ty = threadIdx.y;
const int i = threadIdx.x + ghost_cells;
const int j = threadIdx.y + ghost_cells;
const int i = tx + 1; //Skip local ghost cells, i.e., +1
const int j = ty + 1;
//Fix boundary conditions
if (ti == 1) {
Q[0][j][i-1] = Q[0][j][i];
Q[1][j][i-1] = -Q[1][j][i];
Q[2][j][i-1] = Q[2][j][i];
// West boundary
if (ti == ghost_cells) {
Q[j][i-1] = scale_east_west*Q[j][i];
}
if (ti == nx_) {
Q[0][j][i+1] = Q[0][j][i];
Q[1][j][i+1] = -Q[1][j][i];
Q[2][j][i+1] = Q[2][j][i];
if (ghost_cells >= 2 && ti == ghost_cells + 1) {
Q[j][i-3] = scale_east_west*Q[j][i];
}
if (tj == 1) {
Q[0][j-1][i] = Q[0][j][i];
Q[1][j-1][i] = Q[1][j][i];
Q[2][j-1][i] = -Q[2][j][i];
if (ghost_cells >= 3 && ti == ghost_cells + 2) {
Q[j][i-5] = scale_east_west*Q[j][i];
}
if (tj == ny_) {
Q[0][j+1][i] = Q[0][j][i];
Q[1][j+1][i] = Q[1][j][i];
Q[2][j+1][i] = -Q[2][j][i];
if (ghost_cells >= 4 && ti == ghost_cells + 3) {
Q[j][i-7] = scale_east_west*Q[j][i];
}
if (ghost_cells >= 5 && ti == ghost_cells + 4) {
Q[j][i-9] = scale_east_west*Q[j][i];
}
// East boundary
if (ti == nx_ + ghost_cells - 1) {
Q[j][i+1] = scale_east_west*Q[j][i];
}
if (ghost_cells >= 2 && ti == nx_ + ghost_cells - 2) {
Q[j][i+3] = scale_east_west*Q[j][i];
}
if (ghost_cells >= 3 && ti == nx_ + ghost_cells - 3) {
Q[j][i+5] = scale_east_west*Q[j][i];
}
if (ghost_cells >= 3 && ti == nx_ + ghost_cells - 4) {
Q[j][i+7] = scale_east_west*Q[j][i];
}
if (ghost_cells >= 3 && ti == nx_ + ghost_cells - 5) {
Q[j][i+9] = scale_east_west*Q[j][i];
}
// South boundary
if (tj == ghost_cells) {
Q[j-1][i] = scale_north_south*Q[j][i];
}
if (ghost_cells >= 2 && tj == ghost_cells + 1) {
Q[j-3][i] = scale_north_south*Q[j][i];
}
if (ghost_cells >= 3 && tj == ghost_cells + 2) {
Q[j-5][i] = scale_north_south*Q[j][i];
}
if (ghost_cells >= 4 && tj == ghost_cells + 3) {
Q[j-7][i] = scale_north_south*Q[j][i];
}
if (ghost_cells >= 5 && tj == ghost_cells + 4) {
Q[j-9][i] = scale_north_south*Q[j][i];
}
// North boundary
if (tj == ny_ + ghost_cells - 1) {
Q[j+1][i] = scale_north_south*Q[j][i];
}
if (ghost_cells >= 2 && tj == ny_ + ghost_cells - 2) {
Q[j+3][i] = scale_north_south*Q[j][i];
}
if (ghost_cells >= 3 && tj == ny_ + ghost_cells - 3) {
Q[j+5][i] = scale_north_south*Q[j][i];
}
if (ghost_cells >= 3 && tj == ny_ + ghost_cells - 4) {
Q[j+7][i] = scale_north_south*Q[j][i];
}
if (ghost_cells >= 3 && tj == ny_ + ghost_cells - 5) {
Q[j+9][i] = scale_north_south*Q[j][i];
}
}
@@ -191,59 +217,9 @@ __device__ void noFlowBoundary1(float Q[3][BLOCK_HEIGHT+2][BLOCK_WIDTH+2], const
/**
* No flow boundary conditions for the shallow water equations
* with two ghost cells in each direction
*/
__device__ void noFlowBoundary2(float Q[3][BLOCK_HEIGHT+4][BLOCK_WIDTH+4], const int nx_, const int ny_) {
//Global index
const int ti = blockDim.x*blockIdx.x + threadIdx.x + 2; //Skip global ghost cells, i.e., +2
const int tj = blockDim.y*blockIdx.y + threadIdx.y + 2;
//Block-local indices
const int tx = threadIdx.x;
const int ty = threadIdx.y;
const int i = tx + 2; //Skip local ghost cells, i.e., +2
const int j = ty + 2;
if (ti == 2) {
Q[0][j][i-1] = Q[0][j][i];
Q[1][j][i-1] = -Q[1][j][i];
Q[2][j][i-1] = Q[2][j][i];
Q[0][j][i-2] = Q[0][j][i+1];
Q[1][j][i-2] = -Q[1][j][i+1];
Q[2][j][i-2] = Q[2][j][i+1];
}
if (ti == nx_+1) {
Q[0][j][i+1] = Q[0][j][i];
Q[1][j][i+1] = -Q[1][j][i];
Q[2][j][i+1] = Q[2][j][i];
Q[0][j][i+2] = Q[0][j][i-1];
Q[1][j][i+2] = -Q[1][j][i-1];
Q[2][j][i+2] = Q[2][j][i-1];
}
if (tj == 2) {
Q[0][j-1][i] = Q[0][j][i];
Q[1][j-1][i] = Q[1][j][i];
Q[2][j-1][i] = -Q[2][j][i];
Q[0][j-2][i] = Q[0][j+1][i];
Q[1][j-2][i] = Q[1][j+1][i];
Q[2][j-2][i] = -Q[2][j+1][i];
}
if (tj == ny_+1) {
Q[0][j+1][i] = Q[0][j][i];
Q[1][j+1][i] = Q[1][j][i];
Q[2][j+1][i] = -Q[2][j][i];
Q[0][j+2][i] = Q[0][j-1][i];
Q[1][j+2][i] = Q[1][j-1][i];
Q[2][j+2][i] = -Q[2][j-1][i];
}
}