Stabilize EScalar CUDA fallback path
This commit is contained in:
@@ -217,6 +217,17 @@ static bool escalar_gpu_rk_enabled() {
|
||||
return enabled != 0;
|
||||
}
|
||||
|
||||
static bool escalar_resident_enabled() {
|
||||
static int enabled = -1;
|
||||
if (enabled < 0) {
|
||||
const char *env = getenv("AMSS_ESCALAR_RESIDENT");
|
||||
const char *experimental = getenv("AMSS_ESCALAR_RESIDENT_EXPERIMENTAL");
|
||||
enabled = (env && atoi(env) != 0 &&
|
||||
experimental && atoi(experimental) != 0) ? 1 : 0;
|
||||
}
|
||||
return enabled != 0;
|
||||
}
|
||||
|
||||
static void try_pin_escalar_host_buffer(void *ptr, size_t bytes) {
|
||||
if (!ptr || bytes == 0 || !escalar_host_pin_enabled())
|
||||
return;
|
||||
@@ -523,6 +534,8 @@ static constexpr int BSSN_STATE_COUNT = 24;
|
||||
static constexpr int BSSN_MATTER_COUNT = 10;
|
||||
static constexpr int BSSN_LK_FIELD_COUNT = 24;
|
||||
static constexpr int BSSN_RESIDENT_BANK_COUNT = 4;
|
||||
static constexpr int ESCALAR_FIELD_COUNT = 2;
|
||||
static constexpr int ESCALAR_RESIDENT_BANK_COUNT = 4;
|
||||
|
||||
static const int k_state_input_slots[BSSN_STATE_COUNT] = {
|
||||
S_chi, S_trK, S_dxx, S_gxy, S_gxz, S_dyy, S_gyz, S_dzz,
|
||||
@@ -599,6 +612,7 @@ struct StepContext {
|
||||
double *d_accum_mem;
|
||||
double *d_escalar0_mem;
|
||||
double *d_escalar_accum_mem;
|
||||
std::array<double *, ESCALAR_RESIDENT_BANK_COUNT> d_escalar_resident_mem;
|
||||
double *d_state_curr_mem;
|
||||
double *d_state_next_mem;
|
||||
std::array<double *, BSSN_RESIDENT_BANK_COUNT> d_resident_mem;
|
||||
@@ -609,6 +623,11 @@ struct StepContext {
|
||||
std::array<double *, BSSN_STATE_COUNT> d_accum;
|
||||
std::array<double *, 2> d_escalar0;
|
||||
std::array<double *, 2> d_escalar_accum;
|
||||
std::array<std::array<double *, ESCALAR_FIELD_COUNT>, ESCALAR_RESIDENT_BANK_COUNT> d_escalar_resident;
|
||||
std::array<std::array<double *, ESCALAR_FIELD_COUNT>, ESCALAR_RESIDENT_BANK_COUNT> escalar_host;
|
||||
std::array<bool, ESCALAR_RESIDENT_BANK_COUNT> escalar_valid;
|
||||
std::array<bool, ESCALAR_RESIDENT_BANK_COUNT> escalar_host_clean;
|
||||
std::array<unsigned long long, ESCALAR_RESIDENT_BANK_COUNT> escalar_age;
|
||||
std::array<double *, BSSN_STATE_COUNT> d_state_curr;
|
||||
std::array<double *, BSSN_STATE_COUNT> d_state_next;
|
||||
std::array<std::array<double *, BSSN_STATE_COUNT>, BSSN_RESIDENT_BANK_COUNT> d_resident;
|
||||
@@ -624,23 +643,35 @@ struct StepContext {
|
||||
bool matter_ready;
|
||||
bool state_ready;
|
||||
int current_bank;
|
||||
int current_escalar_bank;
|
||||
unsigned long long resident_clock;
|
||||
unsigned long long escalar_clock;
|
||||
|
||||
StepContext()
|
||||
: d_state0_mem(nullptr), d_accum_mem(nullptr),
|
||||
d_escalar0_mem(nullptr), d_escalar_accum_mem(nullptr),
|
||||
d_escalar_resident_mem{},
|
||||
d_state_curr_mem(nullptr), d_state_next_mem(nullptr),
|
||||
d_resident_mem{},
|
||||
d_matter_mem(nullptr), d_comm_mem(nullptr), h_comm_mem(nullptr),
|
||||
cap_all(0), cap_comm(0), h_comm_pinned(false), cap_h_comm(0),
|
||||
matter_ready(false), state_ready(false),
|
||||
current_bank(-1), resident_clock(0)
|
||||
current_bank(-1), current_escalar_bank(-1),
|
||||
resident_clock(0), escalar_clock(0)
|
||||
{
|
||||
d_escalar_resident_mem.fill(nullptr);
|
||||
d_resident_mem.fill(nullptr);
|
||||
d_state0.fill(nullptr);
|
||||
d_accum.fill(nullptr);
|
||||
d_escalar0.fill(nullptr);
|
||||
d_escalar_accum.fill(nullptr);
|
||||
for (int b = 0; b < ESCALAR_RESIDENT_BANK_COUNT; ++b) {
|
||||
d_escalar_resident[b].fill(nullptr);
|
||||
escalar_host[b].fill(nullptr);
|
||||
}
|
||||
escalar_valid.fill(false);
|
||||
escalar_host_clean.fill(false);
|
||||
escalar_age.fill(0);
|
||||
d_state_curr.fill(nullptr);
|
||||
d_state_next.fill(nullptr);
|
||||
for (int b = 0; b < BSSN_RESIDENT_BANK_COUNT; ++b) {
|
||||
@@ -659,6 +690,7 @@ struct StepAllocation {
|
||||
double *d_accum_mem;
|
||||
double *d_escalar0_mem;
|
||||
double *d_escalar_accum_mem;
|
||||
std::array<double *, ESCALAR_RESIDENT_BANK_COUNT> d_escalar_resident_mem;
|
||||
std::array<double *, BSSN_RESIDENT_BANK_COUNT> d_resident_mem;
|
||||
double *d_matter_mem;
|
||||
double *d_comm_mem;
|
||||
@@ -681,6 +713,7 @@ static StepAllocation empty_step_allocation()
|
||||
alloc.d_accum_mem = nullptr;
|
||||
alloc.d_escalar0_mem = nullptr;
|
||||
alloc.d_escalar_accum_mem = nullptr;
|
||||
alloc.d_escalar_resident_mem.fill(nullptr);
|
||||
alloc.d_resident_mem.fill(nullptr);
|
||||
alloc.d_matter_mem = nullptr;
|
||||
alloc.d_comm_mem = nullptr;
|
||||
@@ -704,6 +737,7 @@ static StepAllocation detach_step_allocation(StepContext &ctx)
|
||||
alloc.d_accum_mem = ctx.d_accum_mem;
|
||||
alloc.d_escalar0_mem = ctx.d_escalar0_mem;
|
||||
alloc.d_escalar_accum_mem = ctx.d_escalar_accum_mem;
|
||||
alloc.d_escalar_resident_mem = ctx.d_escalar_resident_mem;
|
||||
alloc.d_resident_mem = ctx.d_resident_mem;
|
||||
alloc.d_matter_mem = ctx.d_matter_mem;
|
||||
alloc.d_comm_mem = ctx.d_comm_mem;
|
||||
@@ -716,6 +750,7 @@ static StepAllocation detach_step_allocation(StepContext &ctx)
|
||||
ctx.d_accum_mem = nullptr;
|
||||
ctx.d_escalar0_mem = nullptr;
|
||||
ctx.d_escalar_accum_mem = nullptr;
|
||||
ctx.d_escalar_resident_mem.fill(nullptr);
|
||||
ctx.d_state_curr_mem = nullptr;
|
||||
ctx.d_state_next_mem = nullptr;
|
||||
ctx.d_resident_mem.fill(nullptr);
|
||||
@@ -729,11 +764,20 @@ static StepAllocation detach_step_allocation(StepContext &ctx)
|
||||
ctx.matter_ready = false;
|
||||
ctx.state_ready = false;
|
||||
ctx.current_bank = -1;
|
||||
ctx.current_escalar_bank = -1;
|
||||
ctx.resident_clock = 0;
|
||||
ctx.escalar_clock = 0;
|
||||
ctx.d_state0.fill(nullptr);
|
||||
ctx.d_accum.fill(nullptr);
|
||||
ctx.d_escalar0.fill(nullptr);
|
||||
ctx.d_escalar_accum.fill(nullptr);
|
||||
for (int b = 0; b < ESCALAR_RESIDENT_BANK_COUNT; ++b) {
|
||||
ctx.d_escalar_resident[b].fill(nullptr);
|
||||
ctx.escalar_host[b].fill(nullptr);
|
||||
}
|
||||
ctx.escalar_valid.fill(false);
|
||||
ctx.escalar_host_clean.fill(false);
|
||||
ctx.escalar_age.fill(0);
|
||||
ctx.d_state_curr.fill(nullptr);
|
||||
ctx.d_state_next.fill(nullptr);
|
||||
for (int b = 0; b < BSSN_RESIDENT_BANK_COUNT; ++b) {
|
||||
@@ -753,6 +797,7 @@ static void attach_step_allocation(StepContext &ctx, const StepAllocation &alloc
|
||||
ctx.d_accum_mem = alloc.d_accum_mem;
|
||||
ctx.d_escalar0_mem = alloc.d_escalar0_mem;
|
||||
ctx.d_escalar_accum_mem = alloc.d_escalar_accum_mem;
|
||||
ctx.d_escalar_resident_mem = alloc.d_escalar_resident_mem;
|
||||
ctx.d_resident_mem = alloc.d_resident_mem;
|
||||
ctx.d_state_curr_mem = nullptr;
|
||||
ctx.d_state_next_mem = nullptr;
|
||||
@@ -766,11 +811,19 @@ static void attach_step_allocation(StepContext &ctx, const StepAllocation &alloc
|
||||
ctx.matter_ready = false;
|
||||
ctx.state_ready = false;
|
||||
ctx.current_bank = -1;
|
||||
ctx.current_escalar_bank = -1;
|
||||
ctx.resident_clock = 0;
|
||||
ctx.escalar_clock = 0;
|
||||
for (int b = 0; b < BSSN_RESIDENT_BANK_COUNT; ++b) {
|
||||
ctx.resident_host[b].fill(nullptr);
|
||||
ctx.resident_host_clean[b].fill(0);
|
||||
}
|
||||
for (int b = 0; b < ESCALAR_RESIDENT_BANK_COUNT; ++b) {
|
||||
ctx.escalar_host[b].fill(nullptr);
|
||||
ctx.escalar_valid[b] = false;
|
||||
ctx.escalar_host_clean[b] = false;
|
||||
ctx.escalar_age[b] = 0;
|
||||
}
|
||||
ctx.resident_age.fill(0);
|
||||
ctx.resident_valid.fill(false);
|
||||
}
|
||||
@@ -883,6 +936,12 @@ static StepContext &ensure_step_ctx(void *block_tag, size_t all)
|
||||
ctx.d_escalar_accum[i] = ctx.d_escalar_accum_mem + (size_t)i * all;
|
||||
}
|
||||
}
|
||||
for (int b = 0; b < ESCALAR_RESIDENT_BANK_COUNT; ++b) {
|
||||
if (ctx.d_escalar_resident_mem[b]) {
|
||||
for (int i = 0; i < ESCALAR_FIELD_COUNT; ++i)
|
||||
ctx.d_escalar_resident[b][i] = ctx.d_escalar_resident_mem[b] + (size_t)i * all;
|
||||
}
|
||||
}
|
||||
if (ctx.current_bank >= 0) {
|
||||
ctx.d_state_curr_mem = ctx.d_resident_mem[ctx.current_bank];
|
||||
ctx.d_state_curr = ctx.d_resident[ctx.current_bank];
|
||||
@@ -899,10 +958,19 @@ static void ensure_escalar_buffers(StepContext &ctx, size_t all)
|
||||
CUDA_CHECK(cudaMalloc(&ctx.d_escalar0_mem, 2 * ctx.cap_all * sizeof(double)));
|
||||
if (!ctx.d_escalar_accum_mem)
|
||||
CUDA_CHECK(cudaMalloc(&ctx.d_escalar_accum_mem, 2 * ctx.cap_all * sizeof(double)));
|
||||
for (int b = 0; b < ESCALAR_RESIDENT_BANK_COUNT; ++b) {
|
||||
if (!ctx.d_escalar_resident_mem[b])
|
||||
CUDA_CHECK(cudaMalloc(&ctx.d_escalar_resident_mem[b],
|
||||
ESCALAR_FIELD_COUNT * ctx.cap_all * sizeof(double)));
|
||||
}
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
ctx.d_escalar0[i] = ctx.d_escalar0_mem + (size_t)i * all;
|
||||
ctx.d_escalar_accum[i] = ctx.d_escalar_accum_mem + (size_t)i * all;
|
||||
}
|
||||
for (int b = 0; b < ESCALAR_RESIDENT_BANK_COUNT; ++b) {
|
||||
for (int i = 0; i < ESCALAR_FIELD_COUNT; ++i)
|
||||
ctx.d_escalar_resident[b][i] = ctx.d_escalar_resident_mem[b] + (size_t)i * all;
|
||||
}
|
||||
}
|
||||
|
||||
static void release_step_ctx(void *block_tag)
|
||||
@@ -2744,6 +2812,28 @@ static void gpu_copy_patch_boundary_batch(int all,
|
||||
touch_zmin, touch_zmax);
|
||||
}
|
||||
|
||||
static void gpu_copy_escalar_patch_boundary(int all,
|
||||
int touch_xmin, int touch_xmax,
|
||||
int touch_ymin, int touch_ymax,
|
||||
int touch_zmin, int touch_zmax)
|
||||
{
|
||||
if (!(touch_xmin || touch_xmax || touch_ymin || touch_ymax || touch_zmin || touch_zmax))
|
||||
return;
|
||||
|
||||
PatchBoundaryTables tables = {};
|
||||
tables.src_fields[0] = g_buf.slot[S_S_arr];
|
||||
tables.src_fields[1] = g_buf.slot[S_f_arr];
|
||||
tables.dst_fields[0] = g_buf.slot[S_Gamxa];
|
||||
tables.dst_fields[1] = g_buf.slot[S_Gamya];
|
||||
|
||||
dim3 launch_grid((unsigned int)grid((size_t)all), (unsigned int)ESCALAR_FIELD_COUNT);
|
||||
kern_copy_patch_boundary_batched<<<launch_grid, BLK>>>(
|
||||
tables,
|
||||
touch_xmin, touch_xmax,
|
||||
touch_ymin, touch_ymax,
|
||||
touch_zmin, touch_zmax);
|
||||
}
|
||||
|
||||
__global__ void kern_enforce_ga_cuda(double * __restrict__ dxx,
|
||||
double * __restrict__ gxy,
|
||||
double * __restrict__ gxz,
|
||||
@@ -5224,6 +5314,143 @@ static bool any_resident_bank_valid(const StepContext &ctx)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool escalar_key_usable(double **host_key)
|
||||
{
|
||||
return host_key && host_key[0] && host_key[1];
|
||||
}
|
||||
|
||||
static bool escalar_key_matches(const StepContext &ctx, int bank, double **host_key)
|
||||
{
|
||||
if (!escalar_key_usable(host_key) ||
|
||||
bank < 0 || bank >= ESCALAR_RESIDENT_BANK_COUNT)
|
||||
return false;
|
||||
return ctx.escalar_host[bank][0] == host_key[0] &&
|
||||
ctx.escalar_host[bank][1] == host_key[1];
|
||||
}
|
||||
|
||||
static int find_escalar_bank(const StepContext &ctx, double **host_key)
|
||||
{
|
||||
if (!escalar_key_usable(host_key)) return -1;
|
||||
for (int b = 0; b < ESCALAR_RESIDENT_BANK_COUNT; ++b) {
|
||||
if (escalar_key_matches(ctx, b, host_key))
|
||||
return b;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void mark_escalar_current_bank(StepContext &ctx, int bank)
|
||||
{
|
||||
if (bank >= 0 && bank < ESCALAR_RESIDENT_BANK_COUNT)
|
||||
ctx.current_escalar_bank = bank;
|
||||
}
|
||||
|
||||
static int choose_escalar_bank_for_reuse(StepContext &ctx, int avoid_bank)
|
||||
{
|
||||
for (int b = 0; b < ESCALAR_RESIDENT_BANK_COUNT; ++b) {
|
||||
if (b != avoid_bank && !ctx.escalar_valid[b])
|
||||
return b;
|
||||
}
|
||||
int best = -1;
|
||||
unsigned long long best_age = 0;
|
||||
for (int b = 0; b < ESCALAR_RESIDENT_BANK_COUNT; ++b) {
|
||||
if (b == avoid_bank) continue;
|
||||
if (best < 0 || ctx.escalar_age[b] < best_age) {
|
||||
best = b;
|
||||
best_age = ctx.escalar_age[b];
|
||||
}
|
||||
}
|
||||
if (best < 0) best = 0;
|
||||
ctx.escalar_valid[best] = false;
|
||||
ctx.escalar_host_clean[best] = false;
|
||||
ctx.escalar_host[best].fill(nullptr);
|
||||
ctx.escalar_age[best] = 0;
|
||||
return best;
|
||||
}
|
||||
|
||||
static void assign_escalar_key(StepContext &ctx, int bank, double **host_key)
|
||||
{
|
||||
ctx.escalar_host[bank][0] = host_key[0];
|
||||
ctx.escalar_host[bank][1] = host_key[1];
|
||||
ctx.escalar_host_clean[bank] = false;
|
||||
ctx.escalar_age[bank] = ++ctx.escalar_clock;
|
||||
}
|
||||
|
||||
static int ensure_escalar_bank(StepContext &ctx,
|
||||
double **host_key,
|
||||
size_t all,
|
||||
bool upload_if_missing,
|
||||
int avoid_bank = -1)
|
||||
{
|
||||
if (!escalar_key_usable(host_key))
|
||||
return -1;
|
||||
ensure_escalar_buffers(ctx, all);
|
||||
int bank = find_escalar_bank(ctx, host_key);
|
||||
if (bank < 0) {
|
||||
bank = choose_escalar_bank_for_reuse(ctx, avoid_bank);
|
||||
assign_escalar_key(ctx, bank, host_key);
|
||||
}
|
||||
ctx.escalar_age[bank] = ++ctx.escalar_clock;
|
||||
if (!ctx.escalar_valid[bank] && upload_if_missing) {
|
||||
const size_t bytes = all * sizeof(double);
|
||||
CUDA_CHECK(cudaMemcpyAsync(ctx.d_escalar_resident[bank][0], host_key[0],
|
||||
bytes, cudaMemcpyHostToDevice));
|
||||
CUDA_CHECK(cudaMemcpyAsync(ctx.d_escalar_resident[bank][1], host_key[1],
|
||||
bytes, cudaMemcpyHostToDevice));
|
||||
ctx.escalar_valid[bank] = true;
|
||||
ctx.escalar_host_clean[bank] = true;
|
||||
}
|
||||
return bank;
|
||||
}
|
||||
|
||||
static int reserve_escalar_output_bank(StepContext &ctx,
|
||||
double **host_key,
|
||||
size_t all,
|
||||
int input_bank)
|
||||
{
|
||||
if (!escalar_key_usable(host_key))
|
||||
return -1;
|
||||
ensure_escalar_buffers(ctx, all);
|
||||
if (escalar_key_matches(ctx, input_bank, host_key))
|
||||
return input_bank;
|
||||
int bank = find_escalar_bank(ctx, host_key);
|
||||
if (bank < 0)
|
||||
bank = choose_escalar_bank_for_reuse(ctx, input_bank);
|
||||
assign_escalar_key(ctx, bank, host_key);
|
||||
ctx.escalar_valid[bank] = false;
|
||||
return bank;
|
||||
}
|
||||
|
||||
static void mark_escalar_output_valid(StepContext &ctx, int bank)
|
||||
{
|
||||
if (bank < 0 || bank >= ESCALAR_RESIDENT_BANK_COUNT) return;
|
||||
ctx.escalar_valid[bank] = true;
|
||||
ctx.escalar_host_clean[bank] = false;
|
||||
ctx.escalar_age[bank] = ++ctx.escalar_clock;
|
||||
mark_escalar_current_bank(ctx, bank);
|
||||
}
|
||||
|
||||
static int active_or_keyed_escalar_bank(StepContext &ctx,
|
||||
double **host_key,
|
||||
size_t all,
|
||||
bool upload_if_missing)
|
||||
{
|
||||
if (escalar_key_usable(host_key)) {
|
||||
int bank = ensure_escalar_bank(ctx, host_key, all, upload_if_missing);
|
||||
mark_escalar_current_bank(ctx, bank);
|
||||
return bank;
|
||||
}
|
||||
if (ctx.current_escalar_bank >= 0 &&
|
||||
ctx.escalar_valid[ctx.current_escalar_bank])
|
||||
return ctx.current_escalar_bank;
|
||||
for (int b = 0; b < ESCALAR_RESIDENT_BANK_COUNT; ++b) {
|
||||
if (ctx.escalar_valid[b]) {
|
||||
mark_escalar_current_bank(ctx, b);
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void update_state_ready(StepContext &ctx)
|
||||
{
|
||||
ctx.state_ready = any_resident_bank_valid(ctx);
|
||||
@@ -7105,12 +7332,23 @@ int bssn_cuda_compute_escalar_matter(void *block_tag,
|
||||
g_buf.slot[S_Ayy], g_buf.slot[S_Ayz], g_buf.slot[S_Azz]);
|
||||
set_resident_host_clean(ctx, input_bank, false);
|
||||
}
|
||||
try_pin_escalar_host_buffer(Sphi_host, bytes);
|
||||
try_pin_escalar_host_buffer(Spi_host, bytes);
|
||||
try_pin_escalar_host_buffer(Sphi_rhs_host, bytes);
|
||||
try_pin_escalar_host_buffer(Spi_rhs_host, bytes);
|
||||
CUDA_CHECK(cudaMemcpyAsync(g_buf.slot[S_S_arr], Sphi_host, bytes, cudaMemcpyHostToDevice));
|
||||
CUDA_CHECK(cudaMemcpyAsync(g_buf.slot[S_f_arr], Spi_host, bytes, cudaMemcpyHostToDevice));
|
||||
double *scalar_in_key[ESCALAR_FIELD_COUNT] = { Sphi_host, Spi_host };
|
||||
const bool use_escalar_resident = escalar_resident_enabled() && escalar_gpu_rk_enabled();
|
||||
if (use_escalar_resident) {
|
||||
const int scalar_bank = ensure_escalar_bank(ctx, scalar_in_key, all, true);
|
||||
if (scalar_bank < 0) return 1;
|
||||
CUDA_CHECK(cudaMemcpyAsync(g_buf.slot[S_S_arr], ctx.d_escalar_resident[scalar_bank][0],
|
||||
bytes, cudaMemcpyDeviceToDevice));
|
||||
CUDA_CHECK(cudaMemcpyAsync(g_buf.slot[S_f_arr], ctx.d_escalar_resident[scalar_bank][1],
|
||||
bytes, cudaMemcpyDeviceToDevice));
|
||||
} else {
|
||||
try_pin_escalar_host_buffer(Sphi_host, bytes);
|
||||
try_pin_escalar_host_buffer(Spi_host, bytes);
|
||||
try_pin_escalar_host_buffer(Sphi_rhs_host, bytes);
|
||||
try_pin_escalar_host_buffer(Spi_rhs_host, bytes);
|
||||
CUDA_CHECK(cudaMemcpyAsync(g_buf.slot[S_S_arr], Sphi_host, bytes, cudaMemcpyHostToDevice));
|
||||
CUDA_CHECK(cudaMemcpyAsync(g_buf.slot[S_f_arr], Spi_host, bytes, cudaMemcpyHostToDevice));
|
||||
}
|
||||
|
||||
double *src_fields[3] = {
|
||||
g_buf.slot[S_chi], g_buf.slot[S_Lap], g_buf.slot[S_S_arr]
|
||||
@@ -7195,7 +7433,16 @@ int bssn_cuda_escalar_finalize_scalar_fields(void *block_tag,
|
||||
|
||||
const size_t all = (size_t)ex[0] * ex[1] * ex[2];
|
||||
const size_t bytes = all * sizeof(double);
|
||||
int touch_xmin = 0, touch_xmax = 0;
|
||||
int touch_ymin = 0, touch_ymax = 0;
|
||||
int touch_zmin = 0, touch_zmax = 0;
|
||||
setup_grid_params(ex, X, Y, Z, Symmetry, eps, precor);
|
||||
if (Lev > 0) {
|
||||
compute_patch_boundary_flags(ex, X, Y, Z, bbox, Symmetry,
|
||||
touch_xmin, touch_xmax,
|
||||
touch_ymin, touch_ymax,
|
||||
touch_zmin, touch_zmax);
|
||||
}
|
||||
StepContext &ctx = ensure_step_ctx(block_tag, all);
|
||||
ensure_escalar_buffers(ctx, all);
|
||||
|
||||
@@ -7221,11 +7468,29 @@ int bssn_cuda_escalar_finalize_scalar_fields(void *block_tag,
|
||||
ctx.d_escalar_accum[0], dT, RK4);
|
||||
kern_rk4_finalize<<<grid(all), BLK>>>(ctx.d_escalar0[1], g_buf.slot[S_Gamya],
|
||||
ctx.d_escalar_accum[1], dT, RK4);
|
||||
if (Lev > 0) {
|
||||
gpu_copy_escalar_patch_boundary((int)all,
|
||||
touch_xmin, touch_xmax,
|
||||
touch_ymin, touch_ymax,
|
||||
touch_zmin, touch_zmax);
|
||||
}
|
||||
|
||||
try_pin_escalar_host_buffer(Sphi_out_host, bytes);
|
||||
try_pin_escalar_host_buffer(Spi_out_host, bytes);
|
||||
CUDA_CHECK(cudaMemcpyAsync(Sphi_out_host, g_buf.slot[S_Gamxa], bytes, cudaMemcpyDeviceToHost));
|
||||
CUDA_CHECK(cudaMemcpyAsync(Spi_out_host, g_buf.slot[S_Gamya], bytes, cudaMemcpyDeviceToHost));
|
||||
if (escalar_resident_enabled()) {
|
||||
double *scalar_out_key[ESCALAR_FIELD_COUNT] = { Sphi_out_host, Spi_out_host };
|
||||
const int input_bank = find_escalar_bank(ctx, scalar_out_key);
|
||||
const int out_bank = reserve_escalar_output_bank(ctx, scalar_out_key, all, input_bank);
|
||||
if (out_bank < 0) return 1;
|
||||
CUDA_CHECK(cudaMemcpyAsync(ctx.d_escalar_resident[out_bank][0], g_buf.slot[S_Gamxa],
|
||||
bytes, cudaMemcpyDeviceToDevice));
|
||||
CUDA_CHECK(cudaMemcpyAsync(ctx.d_escalar_resident[out_bank][1], g_buf.slot[S_Gamya],
|
||||
bytes, cudaMemcpyDeviceToDevice));
|
||||
mark_escalar_output_valid(ctx, out_bank);
|
||||
} else {
|
||||
try_pin_escalar_host_buffer(Sphi_out_host, bytes);
|
||||
try_pin_escalar_host_buffer(Spi_out_host, bytes);
|
||||
CUDA_CHECK(cudaMemcpyAsync(Sphi_out_host, g_buf.slot[S_Gamxa], bytes, cudaMemcpyDeviceToHost));
|
||||
CUDA_CHECK(cudaMemcpyAsync(Spi_out_host, g_buf.slot[S_Gamya], bytes, cudaMemcpyDeviceToHost));
|
||||
}
|
||||
CUDA_CHECK(cudaDeviceSynchronize());
|
||||
(void)Lev;
|
||||
return 0;
|
||||
@@ -7743,6 +8008,20 @@ int bssn_cuda_restrict_state_batch_to_host_buffer_for_host_views(void *block_tag
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_restrict_state_batch_to_host_buffer(void *block_tag,
|
||||
int state_count,
|
||||
double *host_buffer,
|
||||
int *ex,
|
||||
int sx, int sy, int sz,
|
||||
int fi0, int fj0, int fk0,
|
||||
const double *state_soa)
|
||||
{
|
||||
return bssn_cuda_restrict_state_batch_to_host_buffer_for_host_views(
|
||||
block_tag, nullptr, state_count, host_buffer, ex,
|
||||
sx, sy, sz, fi0, fj0, fk0, state_soa);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_prolong_state_batch_to_host_buffer_for_host_views(void *block_tag,
|
||||
double **state_host_key,
|
||||
@@ -7780,6 +8059,21 @@ int bssn_cuda_prolong_state_batch_to_host_buffer_for_host_views(void *block_tag,
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_prolong_state_batch_to_host_buffer(void *block_tag,
|
||||
int state_count,
|
||||
double *host_buffer,
|
||||
int *ex,
|
||||
int sx, int sy, int sz,
|
||||
int ii0, int jj0, int kk0,
|
||||
int lbc_i, int lbc_j, int lbc_k,
|
||||
const double *state_soa)
|
||||
{
|
||||
return bssn_cuda_prolong_state_batch_to_host_buffer_for_host_views(
|
||||
block_tag, nullptr, state_count, host_buffer, ex,
|
||||
sx, sy, sz, ii0, jj0, kk0, lbc_i, lbc_j, lbc_k, state_soa);
|
||||
}
|
||||
|
||||
static void copy_state_device_batch(void *block_tag,
|
||||
int state_count,
|
||||
double *device_buffer,
|
||||
@@ -8249,6 +8543,335 @@ int bssn_cuda_prolong_state_batch_to_device_buffer_for_host_views(void *block_ta
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int escalar_bank_for_key(void *block_tag,
|
||||
double **scalar_host_key,
|
||||
int *ex,
|
||||
bool upload_if_missing)
|
||||
{
|
||||
if (!escalar_key_usable(scalar_host_key)) return -1;
|
||||
StepContext &ctx = ensure_step_ctx(block_tag, (size_t)ex[0] * ex[1] * ex[2]);
|
||||
return active_or_keyed_escalar_bank(ctx, scalar_host_key,
|
||||
(size_t)ex[0] * ex[1] * ex[2],
|
||||
upload_if_missing);
|
||||
}
|
||||
|
||||
static int copy_escalar_batch_host(void *block_tag,
|
||||
double **scalar_host_key,
|
||||
double *host_buffer,
|
||||
int *ex,
|
||||
int i0, int j0, int k0,
|
||||
int sx, int sy, int sz,
|
||||
cudaMemcpyKind kind)
|
||||
{
|
||||
init_gpu_dispatch();
|
||||
CUDA_CHECK(cudaSetDevice(g_dispatch.my_device));
|
||||
if (!host_buffer || sx <= 0 || sy <= 0 || sz <= 0) return 1;
|
||||
StepContext &ctx = ensure_step_ctx(block_tag, (size_t)ex[0] * ex[1] * ex[2]);
|
||||
const bool unpack = (kind == cudaMemcpyHostToDevice);
|
||||
const int bank = active_or_keyed_escalar_bank(ctx, scalar_host_key,
|
||||
(size_t)ex[0] * ex[1] * ex[2],
|
||||
unpack);
|
||||
if (bank < 0 || (!unpack && !ctx.escalar_valid[bank])) return 1;
|
||||
const int region_all = sx * sy * sz;
|
||||
double *d_comm = ensure_step_comm_buffer(ctx, (size_t)ESCALAR_FIELD_COUNT * region_all);
|
||||
dim3 launch_grid((unsigned int)grid((size_t)region_all),
|
||||
(unsigned int)ESCALAR_FIELD_COUNT);
|
||||
if (kind == cudaMemcpyDeviceToHost) {
|
||||
kern_pack_state_region_batch<<<launch_grid, BLK>>>(
|
||||
ctx.d_escalar_resident_mem[bank], d_comm,
|
||||
ex[0], ex[1], i0, j0, k0, sx, sy, sz,
|
||||
region_all, ESCALAR_FIELD_COUNT,
|
||||
ex[0] * ex[1] * ex[2]);
|
||||
CUDA_CHECK(cudaMemcpy(host_buffer, d_comm,
|
||||
(size_t)ESCALAR_FIELD_COUNT * region_all * sizeof(double),
|
||||
cudaMemcpyDeviceToHost));
|
||||
} else {
|
||||
CUDA_CHECK(cudaMemcpy(d_comm, host_buffer,
|
||||
(size_t)ESCALAR_FIELD_COUNT * region_all * sizeof(double),
|
||||
cudaMemcpyHostToDevice));
|
||||
kern_unpack_state_region_batch<<<launch_grid, BLK>>>(
|
||||
ctx.d_escalar_resident_mem[bank], d_comm,
|
||||
ex[0], ex[1], i0, j0, k0, sx, sy, sz,
|
||||
region_all, ESCALAR_FIELD_COUNT,
|
||||
ex[0] * ex[1] * ex[2]);
|
||||
mark_escalar_output_valid(ctx, bank);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int copy_escalar_batch_device(void *block_tag,
|
||||
double **scalar_host_key,
|
||||
double *device_buffer,
|
||||
int *ex,
|
||||
int i0, int j0, int k0,
|
||||
int sx, int sy, int sz,
|
||||
bool pack)
|
||||
{
|
||||
init_gpu_dispatch();
|
||||
CUDA_CHECK(cudaSetDevice(g_dispatch.my_device));
|
||||
if (!device_buffer || sx <= 0 || sy <= 0 || sz <= 0) return 1;
|
||||
StepContext &ctx = ensure_step_ctx(block_tag, (size_t)ex[0] * ex[1] * ex[2]);
|
||||
const int bank = active_or_keyed_escalar_bank(ctx, scalar_host_key,
|
||||
(size_t)ex[0] * ex[1] * ex[2],
|
||||
!pack);
|
||||
if (bank < 0 || (pack && !ctx.escalar_valid[bank])) return 1;
|
||||
const int region_all = sx * sy * sz;
|
||||
dim3 launch_grid((unsigned int)grid((size_t)region_all),
|
||||
(unsigned int)ESCALAR_FIELD_COUNT);
|
||||
if (pack) {
|
||||
kern_pack_state_region_batch<<<launch_grid, BLK>>>(
|
||||
ctx.d_escalar_resident_mem[bank], device_buffer,
|
||||
ex[0], ex[1], i0, j0, k0, sx, sy, sz,
|
||||
region_all, ESCALAR_FIELD_COUNT,
|
||||
ex[0] * ex[1] * ex[2]);
|
||||
} else {
|
||||
kern_unpack_state_region_batch<<<launch_grid, BLK>>>(
|
||||
ctx.d_escalar_resident_mem[bank], device_buffer,
|
||||
ex[0], ex[1], i0, j0, k0, sx, sy, sz,
|
||||
region_all, ESCALAR_FIELD_COUNT,
|
||||
ex[0] * ex[1] * ex[2]);
|
||||
mark_escalar_output_valid(ctx, bank);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int restrict_escalar_batch(void *block_tag,
|
||||
double **scalar_host_key,
|
||||
void *buffer,
|
||||
int *ex,
|
||||
int sx, int sy, int sz,
|
||||
int fi0, int fj0, int fk0,
|
||||
const double *scalar_soa,
|
||||
bool device_buffer)
|
||||
{
|
||||
init_gpu_dispatch();
|
||||
CUDA_CHECK(cudaSetDevice(g_dispatch.my_device));
|
||||
if (!buffer || sx <= 0 || sy <= 0 || sz <= 0) return 1;
|
||||
StepContext &ctx = ensure_step_ctx(block_tag, (size_t)ex[0] * ex[1] * ex[2]);
|
||||
const int bank = active_or_keyed_escalar_bank(ctx, scalar_host_key,
|
||||
(size_t)ex[0] * ex[1] * ex[2],
|
||||
false);
|
||||
if (bank < 0 || !ctx.escalar_valid[bank]) return 1;
|
||||
const int region_all = sx * sy * sz;
|
||||
double *d_comm = device_buffer ? (double *)buffer :
|
||||
ensure_step_comm_buffer(ctx, (size_t)ESCALAR_FIELD_COUNT * region_all);
|
||||
upload_comm_state_soa(scalar_soa, ESCALAR_FIELD_COUNT);
|
||||
dim3 launch_grid((unsigned int)grid((size_t)region_all),
|
||||
(unsigned int)ESCALAR_FIELD_COUNT);
|
||||
kern_restrict_state_region_batch<<<launch_grid, BLK>>>(
|
||||
ctx.d_escalar_resident_mem[bank], d_comm,
|
||||
ex[0], ex[1], sx, sy, sz,
|
||||
fi0, fj0, fk0, region_all, ESCALAR_FIELD_COUNT,
|
||||
ex[0] * ex[1] * ex[2]);
|
||||
if (!device_buffer) {
|
||||
CUDA_CHECK(cudaMemcpy(buffer, d_comm,
|
||||
(size_t)ESCALAR_FIELD_COUNT * region_all * sizeof(double),
|
||||
cudaMemcpyDeviceToHost));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int prolong_escalar_batch(void *block_tag,
|
||||
double **scalar_host_key,
|
||||
void *buffer,
|
||||
int *ex,
|
||||
int sx, int sy, int sz,
|
||||
int ii0, int jj0, int kk0,
|
||||
int lbc_i, int lbc_j, int lbc_k,
|
||||
const double *scalar_soa,
|
||||
bool device_buffer)
|
||||
{
|
||||
init_gpu_dispatch();
|
||||
CUDA_CHECK(cudaSetDevice(g_dispatch.my_device));
|
||||
if (!buffer || sx <= 0 || sy <= 0 || sz <= 0) return 1;
|
||||
StepContext &ctx = ensure_step_ctx(block_tag, (size_t)ex[0] * ex[1] * ex[2]);
|
||||
const int bank = active_or_keyed_escalar_bank(ctx, scalar_host_key,
|
||||
(size_t)ex[0] * ex[1] * ex[2],
|
||||
false);
|
||||
if (bank < 0 || !ctx.escalar_valid[bank]) return 1;
|
||||
const int region_all = sx * sy * sz;
|
||||
double *d_comm = device_buffer ? (double *)buffer :
|
||||
ensure_step_comm_buffer(ctx, (size_t)ESCALAR_FIELD_COUNT * region_all);
|
||||
upload_comm_state_soa(scalar_soa, ESCALAR_FIELD_COUNT);
|
||||
dim3 launch_grid((unsigned int)grid((size_t)region_all),
|
||||
(unsigned int)ESCALAR_FIELD_COUNT);
|
||||
kern_prolong_state_region_batch<<<launch_grid, BLK>>>(
|
||||
ctx.d_escalar_resident_mem[bank], d_comm,
|
||||
ex[0], ex[1], sx, sy, sz,
|
||||
ii0, jj0, kk0, lbc_i, lbc_j, lbc_k,
|
||||
region_all, ESCALAR_FIELD_COUNT,
|
||||
ex[0] * ex[1] * ex[2]);
|
||||
if (!device_buffer) {
|
||||
CUDA_CHECK(cudaMemcpy(buffer, d_comm,
|
||||
(size_t)ESCALAR_FIELD_COUNT * region_all * sizeof(double),
|
||||
cudaMemcpyDeviceToHost));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_escalar_has_resident_fields(void *block_tag,
|
||||
double *Sphi_host,
|
||||
double *Spi_host)
|
||||
{
|
||||
init_gpu_dispatch();
|
||||
CUDA_CHECK(cudaSetDevice(g_dispatch.my_device));
|
||||
auto it = g_step_ctx.find(block_tag);
|
||||
if (it == g_step_ctx.end()) return 0;
|
||||
double *key[ESCALAR_FIELD_COUNT] = { Sphi_host, Spi_host };
|
||||
const int bank = find_escalar_bank(it->second, key);
|
||||
return (bank >= 0 && it->second.escalar_valid[bank]) ? 1 : 0;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_escalar_has_any_resident_fields(void *block_tag)
|
||||
{
|
||||
init_gpu_dispatch();
|
||||
CUDA_CHECK(cudaSetDevice(g_dispatch.my_device));
|
||||
auto it = g_step_ctx.find(block_tag);
|
||||
if (it == g_step_ctx.end()) return 0;
|
||||
StepContext &ctx = it->second;
|
||||
if (ctx.current_escalar_bank >= 0 &&
|
||||
ctx.current_escalar_bank < ESCALAR_RESIDENT_BANK_COUNT &&
|
||||
ctx.escalar_valid[ctx.current_escalar_bank])
|
||||
return 1;
|
||||
for (int b = 0; b < ESCALAR_RESIDENT_BANK_COUNT; ++b) {
|
||||
if (ctx.escalar_valid[b])
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_escalar_download_fields_if_present(void *block_tag,
|
||||
int *ex,
|
||||
double *Sphi_host,
|
||||
double *Spi_host)
|
||||
{
|
||||
init_gpu_dispatch();
|
||||
CUDA_CHECK(cudaSetDevice(g_dispatch.my_device));
|
||||
auto it = g_step_ctx.find(block_tag);
|
||||
if (it == g_step_ctx.end()) return 0;
|
||||
double *key[ESCALAR_FIELD_COUNT] = { Sphi_host, Spi_host };
|
||||
StepContext &ctx = it->second;
|
||||
const int bank = find_escalar_bank(ctx, key);
|
||||
if (bank < 0 || !ctx.escalar_valid[bank]) return 0;
|
||||
if (ctx.escalar_host_clean[bank]) return 0;
|
||||
const size_t all = (size_t)ex[0] * ex[1] * ex[2];
|
||||
const size_t bytes = all * sizeof(double);
|
||||
CUDA_CHECK(cudaMemcpyAsync(Sphi_host, ctx.d_escalar_resident[bank][0],
|
||||
bytes, cudaMemcpyDeviceToHost));
|
||||
CUDA_CHECK(cudaMemcpyAsync(Spi_host, ctx.d_escalar_resident[bank][1],
|
||||
bytes, cudaMemcpyDeviceToHost));
|
||||
CUDA_CHECK(cudaDeviceSynchronize());
|
||||
ctx.escalar_host_clean[bank] = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_pack_escalar_batch_to_host_buffer(void *block_tag,
|
||||
double **scalar_host_key,
|
||||
double *host_buffer,
|
||||
int *ex,
|
||||
int i0, int j0, int k0,
|
||||
int sx, int sy, int sz)
|
||||
{
|
||||
return copy_escalar_batch_host(block_tag, scalar_host_key, host_buffer, ex,
|
||||
i0, j0, k0, sx, sy, sz, cudaMemcpyDeviceToHost);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_unpack_escalar_batch_from_host_buffer(void *block_tag,
|
||||
double **scalar_host_key,
|
||||
double *host_buffer,
|
||||
int *ex,
|
||||
int i0, int j0, int k0,
|
||||
int sx, int sy, int sz)
|
||||
{
|
||||
return copy_escalar_batch_host(block_tag, scalar_host_key, host_buffer, ex,
|
||||
i0, j0, k0, sx, sy, sz, cudaMemcpyHostToDevice);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_pack_escalar_batch_to_device_buffer(void *block_tag,
|
||||
double **scalar_host_key,
|
||||
double *device_buffer,
|
||||
int *ex,
|
||||
int i0, int j0, int k0,
|
||||
int sx, int sy, int sz)
|
||||
{
|
||||
return copy_escalar_batch_device(block_tag, scalar_host_key, device_buffer, ex,
|
||||
i0, j0, k0, sx, sy, sz, true);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_unpack_escalar_batch_from_device_buffer(void *block_tag,
|
||||
double **scalar_host_key,
|
||||
double *device_buffer,
|
||||
int *ex,
|
||||
int i0, int j0, int k0,
|
||||
int sx, int sy, int sz)
|
||||
{
|
||||
return copy_escalar_batch_device(block_tag, scalar_host_key, device_buffer, ex,
|
||||
i0, j0, k0, sx, sy, sz, false);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_restrict_escalar_batch_to_host_buffer(void *block_tag,
|
||||
double **scalar_host_key,
|
||||
double *host_buffer,
|
||||
int *ex,
|
||||
int sx, int sy, int sz,
|
||||
int fi0, int fj0, int fk0,
|
||||
const double *scalar_soa)
|
||||
{
|
||||
return restrict_escalar_batch(block_tag, scalar_host_key, host_buffer, ex,
|
||||
sx, sy, sz, fi0, fj0, fk0, scalar_soa, false);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_prolong_escalar_batch_to_host_buffer(void *block_tag,
|
||||
double **scalar_host_key,
|
||||
double *host_buffer,
|
||||
int *ex,
|
||||
int sx, int sy, int sz,
|
||||
int ii0, int jj0, int kk0,
|
||||
int lbc_i, int lbc_j, int lbc_k,
|
||||
const double *scalar_soa)
|
||||
{
|
||||
return prolong_escalar_batch(block_tag, scalar_host_key, host_buffer, ex,
|
||||
sx, sy, sz, ii0, jj0, kk0,
|
||||
lbc_i, lbc_j, lbc_k, scalar_soa, false);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_restrict_escalar_batch_to_device_buffer(void *block_tag,
|
||||
double **scalar_host_key,
|
||||
double *device_buffer,
|
||||
int *ex,
|
||||
int sx, int sy, int sz,
|
||||
int fi0, int fj0, int fk0,
|
||||
const double *scalar_soa)
|
||||
{
|
||||
return restrict_escalar_batch(block_tag, scalar_host_key, device_buffer, ex,
|
||||
sx, sy, sz, fi0, fj0, fk0, scalar_soa, true);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_prolong_escalar_batch_to_device_buffer(void *block_tag,
|
||||
double **scalar_host_key,
|
||||
double *device_buffer,
|
||||
int *ex,
|
||||
int sx, int sy, int sz,
|
||||
int ii0, int jj0, int kk0,
|
||||
int lbc_i, int lbc_j, int lbc_k,
|
||||
const double *scalar_soa)
|
||||
{
|
||||
return prolong_escalar_batch(block_tag, scalar_host_key, device_buffer, ex,
|
||||
sx, sy, sz, ii0, jj0, kk0,
|
||||
lbc_i, lbc_j, lbc_k, scalar_soa, true);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_download_state_subset(void *block_tag,
|
||||
int *ex,
|
||||
@@ -8277,6 +8900,69 @@ int bssn_cuda_upload_state_subset(void *block_tag,
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_prepare_escalar_inter_time_level(void *block_tag,
|
||||
int *ex,
|
||||
double **src1_host_key,
|
||||
double **src2_host_key,
|
||||
double **src3_host_key,
|
||||
double **dst_host_key,
|
||||
int source_count,
|
||||
int tindex)
|
||||
{
|
||||
init_gpu_dispatch();
|
||||
CUDA_CHECK(cudaSetDevice(g_dispatch.my_device));
|
||||
if (source_count != 2 && source_count != 3) return 1;
|
||||
if (!escalar_key_usable(src1_host_key) ||
|
||||
!escalar_key_usable(src2_host_key) ||
|
||||
!escalar_key_usable(dst_host_key))
|
||||
return 1;
|
||||
if (source_count == 3 && !escalar_key_usable(src3_host_key))
|
||||
return 1;
|
||||
|
||||
double c1 = 0.0, c2 = 0.0, c3 = 0.0;
|
||||
if (source_count == 2) {
|
||||
if (tindex == 0) {
|
||||
c1 = 0.5; c2 = 0.5;
|
||||
} else if (tindex == 1) {
|
||||
c1 = 0.75; c2 = 0.25;
|
||||
} else if (tindex == -1) {
|
||||
c1 = 0.25; c2 = 0.75;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (tindex == 0) {
|
||||
c1 = 3.0 / 8.0; c2 = 3.0 / 4.0; c3 = -1.0 / 8.0;
|
||||
} else if (tindex == 1 || tindex == -1) {
|
||||
c1 = 5.0 / 32.0; c2 = 15.0 / 16.0; c3 = -3.0 / 32.0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
const size_t all = (size_t)ex[0] * ex[1] * ex[2];
|
||||
StepContext &ctx = ensure_step_ctx(block_tag, all);
|
||||
const int src1_bank = ensure_escalar_bank(ctx, src1_host_key, all, true);
|
||||
const int src2_bank = ensure_escalar_bank(ctx, src2_host_key, all, true, src1_bank);
|
||||
const int src3_bank = (source_count == 3)
|
||||
? ensure_escalar_bank(ctx, src3_host_key, all, true, src1_bank)
|
||||
: -1;
|
||||
const int dst_bank = reserve_escalar_output_bank(ctx, dst_host_key, all, src1_bank);
|
||||
if (src1_bank < 0 || src2_bank < 0 || (source_count == 3 && src3_bank < 0) || dst_bank < 0)
|
||||
return 1;
|
||||
|
||||
dim3 launch_grid((unsigned int)grid(all), (unsigned int)ESCALAR_FIELD_COUNT);
|
||||
kern_prepare_inter_time_level<<<launch_grid, BLK>>>(
|
||||
ctx.d_escalar_resident_mem[src1_bank],
|
||||
ctx.d_escalar_resident_mem[src2_bank],
|
||||
(source_count == 3) ? ctx.d_escalar_resident_mem[src3_bank] : nullptr,
|
||||
ctx.d_escalar_resident_mem[dst_bank],
|
||||
c1, c2, c3, ESCALAR_FIELD_COUNT, (int)all);
|
||||
mark_escalar_output_valid(ctx, dst_bank);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_prepare_inter_time_level(void *block_tag,
|
||||
int *ex,
|
||||
|
||||
Reference in New Issue
Block a user