79 lines
2.6 KiB
Plaintext
79 lines
2.6 KiB
Plaintext
// CelerisLab -- step/esopull_sync.cu
|
|
// Compact-list EsoPull decode/encode for runtime body topology sync.
|
|
//
|
|
// Decodes a subset of cells from EsoPull backing layout to physical DDF,
|
|
// or encodes physical DDF back to EsoPull backing layout.
|
|
// Each thread handles one cell from a compact index list.
|
|
//
|
|
// Included by kernel_v2.cu. No standalone compilation.
|
|
// ============================================================================
|
|
|
|
#ifndef CELERIS_STEP_ESOPULL_SYNC_CU
|
|
#define CELERIS_STEP_ESOPULL_SYNC_CU
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// DecodeCellsToPhysical: backing layout -> physical DDF (compact list)
|
|
//
|
|
// Uses ``t`` as the step count for EsoPull semantic parity decoding.
|
|
// ---------------------------------------------------------------------------
|
|
__global__ void DecodeCellsToPhysical(
|
|
const fpxx* fi,
|
|
float* fi_phys,
|
|
const unsigned int* cell_idx,
|
|
unsigned int n_cells,
|
|
unsigned long t)
|
|
{
|
|
unsigned int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
|
if (tid >= n_cells) return;
|
|
|
|
unsigned long k = (unsigned long)cell_idx[tid];
|
|
unsigned int x, y; coordinates(k, x, y);
|
|
unsigned long j[NQ]; compute_neighbors(x, y, j);
|
|
|
|
float f[NQ];
|
|
load_physical_node_esopull(k, fi, j, t, f);
|
|
|
|
// DDF-shifting: backing layout stores f-w, unshift to physical for host patch
|
|
#if USE_DDF_SHIFTING
|
|
#pragma unroll
|
|
for (int i = 0; i < NQ; i++)
|
|
f[i] += (float)d_w[i];
|
|
#endif
|
|
|
|
for (int i = 0; i < NQ; i++)
|
|
fi_phys[tid * NQ + i] = f[i];
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// EncodePhysicalToCells: physical DDF -> backing layout (compact list)
|
|
//
|
|
// Inverse of DecodeCellsToPhysical at the SAME completed step count.
|
|
// Conversion only: no collision or time advancement, including unchanged halo.
|
|
// ---------------------------------------------------------------------------
|
|
__global__ void EncodePhysicalToCells(
|
|
fpxx* fi,
|
|
const float* fi_phys,
|
|
const unsigned int* cell_idx,
|
|
unsigned int n_cells,
|
|
unsigned long t)
|
|
{
|
|
unsigned int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
|
if (tid >= n_cells) return;
|
|
|
|
unsigned long k = (unsigned long)cell_idx[tid];
|
|
unsigned int x, y; coordinates(k, x, y);
|
|
unsigned long j[NQ]; compute_neighbors(x, y, j);
|
|
|
|
float f[NQ];
|
|
for (int i = 0; i < NQ; i++)
|
|
f[i] = fi_phys[tid * NQ + i];
|
|
|
|
#if USE_DDF_SHIFTING
|
|
for (int i = 0; i < NQ; ++i) f[i] -= (float)d_w[i];
|
|
#endif
|
|
|
|
store_physical_node_esopull(k, f, fi, j, t);
|
|
}
|
|
|
|
#endif // CELERIS_STEP_ESOPULL_SYNC_CU
|