Optimize BSSN CUDA resident state and CUDA-aware MPI
This commit is contained in:
@@ -6,14 +6,68 @@
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <new>
|
||||
using namespace std;
|
||||
|
||||
#include "Block.h"
|
||||
#include "misc.h"
|
||||
|
||||
Block::Block(int DIM, int *shapei, double *bboxi, int ranki, int ingfsi, int fngfsi, int levi, const int cgpui) : rank(ranki), ingfs(ingfsi), fngfs(fngfsi), lev(levi), cgpu(cgpui)
|
||||
{
|
||||
#include <new>
|
||||
using namespace std;
|
||||
|
||||
#include "Block.h"
|
||||
#include "misc.h"
|
||||
|
||||
#if USE_CUDA_BSSN || USE_CUDA_Z4C
|
||||
#include <cuda_runtime_api.h>
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
bool cuda_pin_gridfuncs_enabled()
|
||||
{
|
||||
static int enabled = -1;
|
||||
if (enabled < 0)
|
||||
{
|
||||
const char *env = getenv("AMSS_CUDA_PIN_GRIDFUNCS");
|
||||
enabled = (env && atoi(env) != 0) ? 1 : 0;
|
||||
}
|
||||
return enabled != 0;
|
||||
}
|
||||
|
||||
double *alloc_gridfunc(size_t count, unsigned char &pinned)
|
||||
{
|
||||
pinned = 0;
|
||||
#if USE_CUDA_BSSN || USE_CUDA_Z4C
|
||||
if (cuda_pin_gridfuncs_enabled())
|
||||
{
|
||||
double *ptr = 0;
|
||||
cudaError_t err = cudaMallocHost((void **)&ptr, count * sizeof(double));
|
||||
if (err == cudaSuccess)
|
||||
{
|
||||
pinned = 1;
|
||||
return ptr;
|
||||
}
|
||||
cudaGetLastError();
|
||||
}
|
||||
#endif
|
||||
return (double *)malloc(sizeof(double) * count);
|
||||
}
|
||||
|
||||
void free_gridfunc(double *ptr, unsigned char pinned)
|
||||
{
|
||||
if (!ptr)
|
||||
return;
|
||||
#if USE_CUDA_BSSN || USE_CUDA_Z4C
|
||||
if (pinned)
|
||||
{
|
||||
cudaFreeHost(ptr);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
(void)pinned;
|
||||
#endif
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Block::Block(int DIM, int *shapei, double *bboxi, int ranki, int ingfsi, int fngfsi, int levi, const int cgpui) : rank(ranki), lev(levi), cgpu(cgpui), ingfs(ingfsi), fngfs(fngfsi), igfs(0), fgfs(0), fgfs_pinned(0)
|
||||
{
|
||||
for (int i = 0; i < dim; i++)
|
||||
X[i] = 0;
|
||||
|
||||
@@ -68,14 +122,15 @@ Block::Block(int DIM, int *shapei, double *bboxi, int ranki, int ingfsi, int fng
|
||||
#endif
|
||||
}
|
||||
|
||||
int nn = shape[0] * shape[1] * shape[2];
|
||||
fgfs = new double *[fngfs];
|
||||
for (int i = 0; i < fngfs; i++)
|
||||
{
|
||||
fgfs[i] = (double *)malloc(sizeof(double) * nn);
|
||||
if (!(fgfs[i]))
|
||||
{
|
||||
cout << "on node#" << rank << ", out of memory when constructing Block." << endl;
|
||||
int nn = shape[0] * shape[1] * shape[2];
|
||||
fgfs = new double *[fngfs];
|
||||
fgfs_pinned = new unsigned char[fngfs];
|
||||
for (int i = 0; i < fngfs; i++)
|
||||
{
|
||||
fgfs[i] = alloc_gridfunc((size_t)nn, fgfs_pinned[i]);
|
||||
if (!(fgfs[i]))
|
||||
{
|
||||
cout << "on node#" << rank << ", out of memory when constructing Block." << endl;
|
||||
MPI_Abort(MPI_COMM_WORLD, 1);
|
||||
}
|
||||
memset(fgfs[i], 0, sizeof(double) * nn);
|
||||
@@ -103,17 +158,19 @@ Block::~Block()
|
||||
{
|
||||
for (int i = 0; i < dim; i++)
|
||||
delete[] X[i];
|
||||
for (int i = 0; i < ingfs; i++)
|
||||
free(igfs[i]);
|
||||
delete[] igfs;
|
||||
for (int i = 0; i < fngfs; i++)
|
||||
free(fgfs[i]);
|
||||
delete[] fgfs;
|
||||
X[0] = X[1] = X[2] = 0;
|
||||
igfs = 0;
|
||||
fgfs = 0;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < ingfs; i++)
|
||||
free(igfs[i]);
|
||||
delete[] igfs;
|
||||
for (int i = 0; i < fngfs; i++)
|
||||
free_gridfunc(fgfs[i], fgfs_pinned ? fgfs_pinned[i] : 0);
|
||||
delete[] fgfs;
|
||||
delete[] fgfs_pinned;
|
||||
X[0] = X[1] = X[2] = 0;
|
||||
igfs = 0;
|
||||
fgfs = 0;
|
||||
fgfs_pinned = 0;
|
||||
}
|
||||
}
|
||||
void Block::checkBlock()
|
||||
{
|
||||
int myrank;
|
||||
@@ -184,12 +241,14 @@ void Block::swapList(MyList<var> *VarList1, MyList<var> *VarList2, int myrank)
|
||||
if (rank == myrank)
|
||||
{
|
||||
MyList<var> *varl1 = VarList1, *varl2 = VarList2;
|
||||
while (varl1 && varl2)
|
||||
{
|
||||
misc::swap<double *>(fgfs[varl1->data->sgfn], fgfs[varl2->data->sgfn]);
|
||||
varl1 = varl1->next;
|
||||
varl2 = varl2->next;
|
||||
}
|
||||
while (varl1 && varl2)
|
||||
{
|
||||
misc::swap<double *>(fgfs[varl1->data->sgfn], fgfs[varl2->data->sgfn]);
|
||||
if (fgfs_pinned)
|
||||
misc::swap<unsigned char>(fgfs_pinned[varl1->data->sgfn], fgfs_pinned[varl2->data->sgfn]);
|
||||
varl1 = varl1->next;
|
||||
varl2 = varl2->next;
|
||||
}
|
||||
if (varl1 || varl2)
|
||||
{
|
||||
cout << "error in Block::swaplist, var lists does not match." << endl;
|
||||
|
||||
@@ -13,14 +13,15 @@ public:
|
||||
int shape[dim];
|
||||
double bbox[2 * dim];
|
||||
double *X[dim];
|
||||
int rank; // where the real data locate in
|
||||
int lev, cgpu;
|
||||
int ingfs, fngfs;
|
||||
int *(*igfs);
|
||||
double *(*fgfs);
|
||||
int rank; // where the real data locate in
|
||||
int lev, cgpu;
|
||||
int ingfs, fngfs;
|
||||
int *(*igfs);
|
||||
double *(*fgfs);
|
||||
unsigned char *fgfs_pinned;
|
||||
|
||||
public:
|
||||
Block() {};
|
||||
Block() : rank(0), lev(0), cgpu(0), ingfs(0), fngfs(0), igfs(0), fgfs(0), fgfs_pinned(0) {};
|
||||
Block(int DIM, int *shapei, double *bboxi, int ranki, int ingfsi, int fngfs, int levi, const int cgpui = 0);
|
||||
|
||||
~Block();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -100,29 +100,36 @@ namespace Parallel
|
||||
MyList<gridseg> **combined_dst;
|
||||
int *send_lengths;
|
||||
int *recv_lengths;
|
||||
double **send_bufs;
|
||||
double **recv_bufs;
|
||||
int *send_buf_caps;
|
||||
int *recv_buf_caps;
|
||||
unsigned char *send_buf_pinned;
|
||||
unsigned char *recv_buf_pinned;
|
||||
MPI_Request *reqs;
|
||||
MPI_Status *stats;
|
||||
double **send_bufs;
|
||||
double **recv_bufs;
|
||||
int *send_buf_caps;
|
||||
int *recv_buf_caps;
|
||||
unsigned char *send_buf_pinned;
|
||||
unsigned char *recv_buf_pinned;
|
||||
unsigned char *send_buf_is_dev;
|
||||
unsigned char *recv_buf_is_dev;
|
||||
int *send_buf_caps_dev;
|
||||
int *recv_buf_caps_dev;
|
||||
double **send_bufs_dev;
|
||||
double **recv_bufs_dev;
|
||||
MPI_Request *reqs;
|
||||
MPI_Status *stats;
|
||||
int max_reqs;
|
||||
bool lengths_valid;
|
||||
int *tc_req_node;
|
||||
int *tc_req_is_recv;
|
||||
int *tc_completed;
|
||||
bool cuda_aware_mode;
|
||||
SyncCache();
|
||||
void invalidate();
|
||||
void destroy();
|
||||
};
|
||||
|
||||
void Sync_cached(MyList<Patch> *PatL, MyList<var> *VarList, int Symmetry, SyncCache &cache);
|
||||
void Sync_ensure_cache(MyList<Patch> *PatL, int Symmetry, SyncCache &cache);
|
||||
void transfer_cached(MyList<gridseg> **src, MyList<gridseg> **dst,
|
||||
MyList<var> *VarList1, MyList<var> *VarList2,
|
||||
int Symmetry, SyncCache &cache);
|
||||
void Sync_cached(MyList<Patch> *PatL, MyList<var> *VarList, int Symmetry, SyncCache &cache);
|
||||
void Sync_ensure_cache(MyList<Patch> *PatL, int Symmetry, SyncCache &cache);
|
||||
void transfer_cached(MyList<gridseg> **src, MyList<gridseg> **dst,
|
||||
MyList<var> *VarList1, MyList<var> *VarList2,
|
||||
int Symmetry, SyncCache &cache);
|
||||
|
||||
struct AsyncSyncState {
|
||||
int req_no;
|
||||
@@ -182,13 +189,13 @@ namespace Parallel
|
||||
MyList<Parallel::gridseg> *clone_gsl(MyList<Parallel::gridseg> *p, bool first_only);
|
||||
MyList<Parallel::gridseg> *build_bulk_gsl(Patch *Pat); // similar to build_owned_gsl0 but does not care rank issue
|
||||
MyList<Parallel::gridseg> *build_bulk_gsl(Block *bp, Patch *Pat);
|
||||
void build_PhysBD_gstl(Patch *Pat, MyList<Parallel::gridseg> *srci, MyList<Parallel::gridseg> *dsti,
|
||||
MyList<Parallel::gridseg> **out_src, MyList<Parallel::gridseg> **out_dst);
|
||||
void PeriodicBD(Patch *Pat, MyList<var> *VarList, int Symmetry);
|
||||
double L2Norm(Patch *Pat, var *vf);
|
||||
void L2Norm7(Patch *Pat, var **vf, double *norms);
|
||||
void checkgsl(MyList<Parallel::gridseg> *pp, bool first_only);
|
||||
void checkvarl(MyList<var> *pp, bool first_only);
|
||||
void build_PhysBD_gstl(Patch *Pat, MyList<Parallel::gridseg> *srci, MyList<Parallel::gridseg> *dsti,
|
||||
MyList<Parallel::gridseg> **out_src, MyList<Parallel::gridseg> **out_dst);
|
||||
void PeriodicBD(Patch *Pat, MyList<var> *VarList, int Symmetry);
|
||||
double L2Norm(Patch *Pat, var *vf);
|
||||
void L2Norm7(Patch *Pat, var **vf, double *norms);
|
||||
void checkgsl(MyList<Parallel::gridseg> *pp, bool first_only);
|
||||
void checkvarl(MyList<var> *pp, bool first_only);
|
||||
MyList<Parallel::gridseg> *divide_gsl(MyList<Parallel::gridseg> *p, Patch *Pat);
|
||||
MyList<Parallel::gridseg> *divide_gs(MyList<Parallel::gridseg> *p, Patch *Pat);
|
||||
void prepare_inter_time_level(Patch *Pat,
|
||||
@@ -220,12 +227,12 @@ namespace Parallel
|
||||
void aligncheck(double *bbox0, double *bboxl, int lev, double *DH0, int *shape);
|
||||
bool point_locat_gsl(double *pox, MyList<Parallel::gridseg> *gsl);
|
||||
void checkpatchlist(MyList<Patch> *PatL, bool buflog);
|
||||
|
||||
double L2Norm(Patch *Pat, var *vf, MPI_Comm Comm_here);
|
||||
void L2Norm7(Patch *Pat, var **vf, double *norms, MPI_Comm Comm_here);
|
||||
bool PatList_Interp_Points(MyList<Patch> *PatL, MyList<var> *VarList,
|
||||
int NN, double **XX,
|
||||
double *Shellf, int Symmetry, MPI_Comm Comm_here);
|
||||
|
||||
double L2Norm(Patch *Pat, var *vf, MPI_Comm Comm_here);
|
||||
void L2Norm7(Patch *Pat, var **vf, double *norms, MPI_Comm Comm_here);
|
||||
bool PatList_Interp_Points(MyList<Patch> *PatL, MyList<var> *VarList,
|
||||
int NN, double **XX,
|
||||
double *Shellf, int Symmetry, MPI_Comm Comm_here);
|
||||
#if (PSTR == 1 || PSTR == 2 || PSTR == 3)
|
||||
MyList<Block> *distribute(MyList<Patch> *PatchLIST, int cpusize, int ingfsi, int fngfsi,
|
||||
bool periodic, int start_rank, int end_rank, int nodes = 0);
|
||||
|
||||
@@ -76,11 +76,36 @@ struct CudaProfileStats {
|
||||
double output_ms;
|
||||
};
|
||||
|
||||
enum RhsStageId {
|
||||
RHS_STAGE_PREP = 0,
|
||||
RHS_STAGE_DERIV1,
|
||||
RHS_STAGE_METRIC,
|
||||
RHS_STAGE_GAUGE_DERIV,
|
||||
RHS_STAGE_GAMMA_CONTRACT,
|
||||
RHS_STAGE_RICCI_DIFF,
|
||||
RHS_STAGE_RICCI_FUSED,
|
||||
RHS_STAGE_CHI,
|
||||
RHS_STAGE_GAUGE_RHS,
|
||||
RHS_STAGE_KODIS,
|
||||
RHS_STAGE_CONSTRAINTS,
|
||||
RHS_STAGE_COUNT
|
||||
};
|
||||
|
||||
struct RhsStageProfileStats {
|
||||
long long calls;
|
||||
double ms[RHS_STAGE_COUNT];
|
||||
};
|
||||
|
||||
static CudaProfileStats &cuda_profile_stats() {
|
||||
static CudaProfileStats stats = {0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
|
||||
return stats;
|
||||
}
|
||||
|
||||
static RhsStageProfileStats &rhs_stage_profile_stats() {
|
||||
static RhsStageProfileStats stats = {};
|
||||
return stats;
|
||||
}
|
||||
|
||||
static bool cuda_profile_enabled() {
|
||||
static int enabled = -1;
|
||||
if (enabled < 0) {
|
||||
@@ -99,6 +124,24 @@ static int cuda_profile_every() {
|
||||
return every;
|
||||
}
|
||||
|
||||
static bool rhs_stage_timing_enabled() {
|
||||
static int enabled = -1;
|
||||
if (enabled < 0) {
|
||||
const char *env = getenv("AMSS_GPU_STAGE_TIMING");
|
||||
enabled = (env && atoi(env) != 0) ? 1 : 0;
|
||||
}
|
||||
return enabled != 0;
|
||||
}
|
||||
|
||||
static int rhs_stage_timing_every() {
|
||||
static int every = -1;
|
||||
if (every < 0) {
|
||||
const char *env = getenv("AMSS_GPU_STAGE_TIMING_EVERY");
|
||||
every = (env && atoi(env) > 0) ? atoi(env) : cuda_profile_every();
|
||||
}
|
||||
return every;
|
||||
}
|
||||
|
||||
static double cuda_profile_now_ms() {
|
||||
using clock = std::chrono::steady_clock;
|
||||
return std::chrono::duration<double, std::milli>(
|
||||
@@ -131,6 +174,36 @@ static void cuda_profile_maybe_log() {
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
static void rhs_stage_profile_accumulate(const double *stage_ms) {
|
||||
if (!rhs_stage_timing_enabled()) return;
|
||||
|
||||
RhsStageProfileStats &stats = rhs_stage_profile_stats();
|
||||
stats.calls++;
|
||||
for (int i = 0; i < RHS_STAGE_COUNT; ++i) {
|
||||
stats.ms[i] += stage_ms[i];
|
||||
}
|
||||
if (stats.calls <= 0 || stats.calls % rhs_stage_timing_every() != 0) return;
|
||||
|
||||
fprintf(stderr,
|
||||
"[AMSS-CUDA-STAGE][rank %d][dev %d] calls=%lld"
|
||||
" prep=%.3f deriv1=%.3f metric=%.3f gauge_deriv=%.3f"
|
||||
" gamma_contract=%.3f ricci_diff=%.3f ricci_fused=%.3f"
|
||||
" chi=%.3f gauge_rhs=%.3f kodis=%.3f constraints=%.3f ms\n",
|
||||
g_dispatch.my_rank, g_dispatch.my_device, stats.calls,
|
||||
stats.ms[RHS_STAGE_PREP] / (double)stats.calls,
|
||||
stats.ms[RHS_STAGE_DERIV1] / (double)stats.calls,
|
||||
stats.ms[RHS_STAGE_METRIC] / (double)stats.calls,
|
||||
stats.ms[RHS_STAGE_GAUGE_DERIV] / (double)stats.calls,
|
||||
stats.ms[RHS_STAGE_GAMMA_CONTRACT] / (double)stats.calls,
|
||||
stats.ms[RHS_STAGE_RICCI_DIFF] / (double)stats.calls,
|
||||
stats.ms[RHS_STAGE_RICCI_FUSED] / (double)stats.calls,
|
||||
stats.ms[RHS_STAGE_CHI] / (double)stats.calls,
|
||||
stats.ms[RHS_STAGE_GAUGE_RHS] / (double)stats.calls,
|
||||
stats.ms[RHS_STAGE_KODIS] / (double)stats.calls,
|
||||
stats.ms[RHS_STAGE_CONSTRAINTS] / (double)stats.calls);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Error checking */
|
||||
/* ------------------------------------------------------------------ */
|
||||
@@ -4643,6 +4716,20 @@ static void compute_patch_boundary_flags(int *ex,
|
||||
static void upload_state_inputs(double **state_host, size_t all)
|
||||
{
|
||||
const size_t bytes = all * sizeof(double);
|
||||
static int direct_upload = -1;
|
||||
if (direct_upload < 0) {
|
||||
const char *env = getenv("AMSS_CUDA_DIRECT_STATE_UPLOAD");
|
||||
const char *pin_env = getenv("AMSS_CUDA_PIN_GRIDFUNCS");
|
||||
direct_upload = env ? ((atoi(env) != 0) ? 1 : 0)
|
||||
: ((pin_env && atoi(pin_env) != 0) ? 1 : 0);
|
||||
}
|
||||
if (direct_upload) {
|
||||
for (int i = 0; i < BSSN_STATE_COUNT; ++i) {
|
||||
CUDA_CHECK(cudaMemcpyAsync(g_buf.slot[k_state_input_slots[i]], state_host[i],
|
||||
bytes, cudaMemcpyHostToDevice));
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < BSSN_STATE_COUNT; ++i) {
|
||||
std::memcpy(g_buf.h_stage + (size_t)i * all, state_host[i], bytes);
|
||||
}
|
||||
@@ -4697,11 +4784,24 @@ static void launch_rhs_pipeline(int all, double eps, int co)
|
||||
{
|
||||
const double SYM = 1.0;
|
||||
const double ANTI = -1.0;
|
||||
const bool stage_timing = rhs_stage_timing_enabled();
|
||||
double stage_ms[RHS_STAGE_COUNT] = {};
|
||||
double stage_t0 = stage_timing ? cuda_profile_now_ms() : 0.0;
|
||||
|
||||
#define D(s) g_buf.slot[s]
|
||||
#define MARK_RHS_STAGE(stage_id) do { \
|
||||
if (stage_timing) { \
|
||||
cuda_profile_sync(); \
|
||||
const double stage_t1 = cuda_profile_now_ms(); \
|
||||
stage_ms[(stage_id)] += stage_t1 - stage_t0; \
|
||||
stage_t0 = stage_t1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
kern_phase1_prep<<<grid(all),BLK>>>(
|
||||
D(S_Lap), D(S_chi), D(S_dxx), D(S_dyy), D(S_dzz),
|
||||
D(S_alpn1), D(S_chin1), D(S_gxx), D(S_gyy), D(S_gzz));
|
||||
MARK_RHS_STAGE(RHS_STAGE_PREP);
|
||||
|
||||
{
|
||||
double *src_fields[] = {
|
||||
@@ -4742,6 +4842,7 @@ static void launch_rhs_pipeline(int all, double eps, int co)
|
||||
src_fields, fx_fields, fy_fields, fz_fields,
|
||||
soa_signs, all);
|
||||
}
|
||||
MARK_RHS_STAGE(RHS_STAGE_DERIV1);
|
||||
|
||||
kern_phase2_metric_rhs<<<grid(all),BLK>>>(
|
||||
D(S_alpn1), D(S_chin1),
|
||||
@@ -4799,6 +4900,7 @@ static void launch_rhs_pipeline(int all, double eps, int co)
|
||||
D(S_Gamzxx), D(S_Gamzxy), D(S_Gamzxz),
|
||||
D(S_Gamzyy), D(S_Gamzyz), D(S_Gamzzz),
|
||||
D(S_Gamx_rhs), D(S_Gamy_rhs), D(S_Gamz_rhs));
|
||||
MARK_RHS_STAGE(RHS_STAGE_METRIC);
|
||||
|
||||
{
|
||||
double *src_fields[] = {D(S_betax), D(S_betay), D(S_betaz)};
|
||||
@@ -4832,6 +4934,7 @@ static void launch_rhs_pipeline(int all, double eps, int co)
|
||||
src_fields, fx_fields, fy_fields, fz_fields,
|
||||
soa_signs, all);
|
||||
}
|
||||
MARK_RHS_STAGE(RHS_STAGE_GAUGE_DERIV);
|
||||
|
||||
kern_phase8_9_gamma_rhs_contract_fused<<<grid(all),BLK>>>(
|
||||
D(S_gupxx), D(S_gupxy), D(S_gupxz),
|
||||
@@ -4854,6 +4957,7 @@ static void launch_rhs_pipeline(int all, double eps, int co)
|
||||
D(S_gxxx),D(S_gxyx),D(S_gxzx),D(S_gyyx),D(S_gyzx),D(S_gzzx),
|
||||
D(S_gxxy),D(S_gxyy),D(S_gxzy),D(S_gyyy),D(S_gyzy),D(S_gzzy),
|
||||
D(S_gxxz),D(S_gxyz),D(S_gxzz),D(S_gyyz),D(S_gyzz),D(S_gzzz));
|
||||
MARK_RHS_STAGE(RHS_STAGE_GAMMA_CONTRACT);
|
||||
|
||||
{
|
||||
double *src_fields[] = {D(S_dxx), D(S_dyy), D(S_dzz), D(S_gxy), D(S_gxz), D(S_gyz)};
|
||||
@@ -4870,6 +4974,7 @@ static void launch_rhs_pipeline(int all, double eps, int co)
|
||||
D(S_gupyy), D(S_gupyz), D(S_gupzz),
|
||||
src_fields, dst_fields, soa_signs, all);
|
||||
}
|
||||
MARK_RHS_STAGE(RHS_STAGE_RICCI_DIFF);
|
||||
|
||||
kern_phase11_ricci_fused<<<grid(all),BLK>>>(
|
||||
D(S_gxx),D(S_gxy),D(S_gxz),D(S_gyy),D(S_gyz),D(S_gzz),
|
||||
@@ -4889,6 +4994,7 @@ static void launch_rhs_pipeline(int all, double eps, int co)
|
||||
D(S_gxxz),D(S_gxyz),D(S_gxzz),D(S_gyyz),D(S_gyzz),D(S_gzzz),
|
||||
D(S_Rxx),D(S_Rxy),D(S_Rxz),
|
||||
D(S_Ryy),D(S_Ryz),D(S_Rzz));
|
||||
MARK_RHS_STAGE(RHS_STAGE_RICCI_FUSED);
|
||||
|
||||
kern_phase12_13_chi_correction_fused<<<grid((size_t)all),BLK>>>(
|
||||
D(S_chi), D(S_chin1),
|
||||
@@ -4904,6 +5010,7 @@ static void launch_rhs_pipeline(int all, double eps, int co)
|
||||
D(S_Gamzyy), D(S_Gamzyz), D(S_Gamzzz),
|
||||
D(S_Rxx), D(S_Rxy), D(S_Rxz),
|
||||
D(S_Ryy), D(S_Ryz), D(S_Rzz));
|
||||
MARK_RHS_STAGE(RHS_STAGE_CHI);
|
||||
|
||||
kern_phase15_trK_Aij_gauge<<<grid(all),BLK>>>(
|
||||
D(S_alpn1), D(S_chin1),
|
||||
@@ -4936,8 +5043,10 @@ static void launch_rhs_pipeline(int all, double eps, int co)
|
||||
D(S_betax_rhs), D(S_betay_rhs), D(S_betaz_rhs),
|
||||
D(S_Gamx_rhs), D(S_Gamy_rhs), D(S_Gamz_rhs),
|
||||
D(S_f_arr), D(S_S_arr));
|
||||
MARK_RHS_STAGE(RHS_STAGE_GAUGE_RHS);
|
||||
|
||||
gpu_lopsided_kodis_state_batch(eps, all);
|
||||
MARK_RHS_STAGE(RHS_STAGE_KODIS);
|
||||
|
||||
if (co == 0) {
|
||||
{
|
||||
@@ -4982,7 +5091,10 @@ static void launch_rhs_pipeline(int all, double eps, int co)
|
||||
D(S_gzzx), D(S_gzzy), D(S_gzzz),
|
||||
D(S_ham_Res), D(S_movx_Res), D(S_movy_Res), D(S_movz_Res));
|
||||
}
|
||||
MARK_RHS_STAGE(RHS_STAGE_CONSTRAINTS);
|
||||
|
||||
rhs_stage_profile_accumulate(stage_ms);
|
||||
#undef MARK_RHS_STAGE
|
||||
#undef D
|
||||
}
|
||||
|
||||
@@ -5196,6 +5308,21 @@ static void download_resident_state(void *block_tag, int *ex, double **state_hos
|
||||
const size_t all = (size_t)ex[0] * ex[1] * ex[2];
|
||||
const size_t bytes = all * sizeof(double);
|
||||
StepContext &ctx = ensure_step_ctx(block_tag, all);
|
||||
static int direct_download = -1;
|
||||
if (direct_download < 0) {
|
||||
const char *env = getenv("AMSS_CUDA_DIRECT_STATE_DOWNLOAD");
|
||||
const char *pin_env = getenv("AMSS_CUDA_PIN_GRIDFUNCS");
|
||||
direct_download = env ? ((atoi(env) != 0) ? 1 : 0)
|
||||
: ((pin_env && atoi(pin_env) != 0) ? 1 : 0);
|
||||
}
|
||||
if (direct_download) {
|
||||
for (int i = 0; i < BSSN_STATE_COUNT; ++i) {
|
||||
CUDA_CHECK(cudaMemcpyAsync(state_host_out[i], ctx.d_state_curr[i],
|
||||
bytes, cudaMemcpyDeviceToHost));
|
||||
}
|
||||
CUDA_CHECK(cudaDeviceSynchronize());
|
||||
return;
|
||||
}
|
||||
CUDA_CHECK(cudaMemcpy(g_buf.h_stage, ctx.d_state_curr_mem,
|
||||
(size_t)BSSN_STATE_COUNT * bytes,
|
||||
cudaMemcpyDeviceToHost));
|
||||
@@ -5902,6 +6029,67 @@ int bssn_cuda_unpack_state_batch_from_host_buffer(void *block_tag,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void copy_state_device_batch(void *block_tag,
|
||||
int state_count,
|
||||
double *device_buffer,
|
||||
const int *ex,
|
||||
int i0, int j0, int k0,
|
||||
int sx, int sy, int sz,
|
||||
int pack_not_unpack)
|
||||
{
|
||||
if (state_count <= 0 || state_count > BSSN_STATE_COUNT) return;
|
||||
if (sx <= 0 || sy <= 0 || sz <= 0) return;
|
||||
|
||||
StepContext &ctx = ensure_step_ctx(block_tag, (size_t)ex[0] * ex[1] * ex[2]);
|
||||
const int region_all = sx * sy * sz;
|
||||
dim3 launch_grid((unsigned int)grid((size_t)region_all),
|
||||
(unsigned int)state_count);
|
||||
|
||||
if (pack_not_unpack) {
|
||||
kern_pack_state_region_batch<<<launch_grid, BLK>>>(
|
||||
ctx.d_state_curr_mem, device_buffer,
|
||||
ex[0], ex[1], i0, j0, k0, sx, sy, sz,
|
||||
region_all, state_count,
|
||||
ex[0] * ex[1] * ex[2]);
|
||||
} else {
|
||||
kern_unpack_state_region_batch<<<launch_grid, BLK>>>(
|
||||
ctx.d_state_curr_mem, device_buffer,
|
||||
ex[0], ex[1], i0, j0, k0, sx, sy, sz,
|
||||
region_all, state_count,
|
||||
ex[0] * ex[1] * ex[2]);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_pack_state_batch_to_device_buffer(void *block_tag,
|
||||
int state_count,
|
||||
double *device_buffer,
|
||||
int *ex,
|
||||
int i0, int j0, int k0,
|
||||
int sx, int sy, int sz)
|
||||
{
|
||||
init_gpu_dispatch();
|
||||
CUDA_CHECK(cudaSetDevice(g_dispatch.my_device));
|
||||
copy_state_device_batch(block_tag, state_count, device_buffer, ex,
|
||||
i0, j0, k0, sx, sy, sz, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_unpack_state_batch_from_device_buffer(void *block_tag,
|
||||
int state_count,
|
||||
double *device_buffer,
|
||||
int *ex,
|
||||
int i0, int j0, int k0,
|
||||
int sx, int sy, int sz)
|
||||
{
|
||||
init_gpu_dispatch();
|
||||
CUDA_CHECK(cudaSetDevice(g_dispatch.my_device));
|
||||
copy_state_device_batch(block_tag, state_count, device_buffer, ex,
|
||||
i0, j0, k0, sx, sy, sz, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int bssn_cuda_download_state_subset(void *block_tag,
|
||||
int *ex,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#ifndef BSSN_RHS_CUDA_H
|
||||
#define BSSN_RHS_CUDA_H
|
||||
|
||||
#ifndef BSSN_RHS_CUDA_H
|
||||
#define BSSN_RHS_CUDA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -9,28 +9,28 @@ enum {
|
||||
BSSN_CUDA_STATE_COUNT = 24,
|
||||
BSSN_CUDA_MATTER_COUNT = 10
|
||||
};
|
||||
|
||||
|
||||
int f_compute_rhs_bssn(int *ex, double &T,
|
||||
double *X, double *Y, double *Z,
|
||||
double *chi, double *trK,
|
||||
double *dxx, double *gxy, double *gxz, double *dyy, double *gyz, double *dzz,
|
||||
double *Axx, double *Axy, double *Axz, double *Ayy, double *Ayz, double *Azz,
|
||||
double *Gamx, double *Gamy, double *Gamz,
|
||||
double *Lap, double *betax, double *betay, double *betaz,
|
||||
double *dtSfx, double *dtSfy, double *dtSfz,
|
||||
double *chi_rhs, double *trK_rhs,
|
||||
double *gxx_rhs, double *gxy_rhs, double *gxz_rhs, double *gyy_rhs, double *gyz_rhs, double *gzz_rhs,
|
||||
double *Axx_rhs, double *Axy_rhs, double *Axz_rhs, double *Ayy_rhs, double *Ayz_rhs, double *Azz_rhs,
|
||||
double *Gamx_rhs, double *Gamy_rhs, double *Gamz_rhs,
|
||||
double *Lap_rhs, double *betax_rhs, double *betay_rhs, double *betaz_rhs,
|
||||
double *dtSfx_rhs, double *dtSfy_rhs, double *dtSfz_rhs,
|
||||
double *rho, double *Sx, double *Sy, double *Sz,
|
||||
double *Sxx, double *Sxy, double *Sxz, double *Syy, double *Syz, double *Szz,
|
||||
double *Gamxxx, double *Gamxxy, double *Gamxxz, double *Gamxyy, double *Gamxyz, double *Gamxzz,
|
||||
double *Gamyxx, double *Gamyxy, double *Gamyxz, double *Gamyyy, double *Gamyyz, double *Gamyzz,
|
||||
double *Gamzxx, double *Gamzxy, double *Gamzxz, double *Gamzyy, double *Gamzyz, double *Gamzzz,
|
||||
double *Rxx, double *Rxy, double *Rxz, double *Ryy, double *Ryz, double *Rzz,
|
||||
double *ham_Res, double *movx_Res, double *movy_Res, double *movz_Res,
|
||||
double *dxx, double *gxy, double *gxz, double *dyy, double *gyz, double *dzz,
|
||||
double *Axx, double *Axy, double *Axz, double *Ayy, double *Ayz, double *Azz,
|
||||
double *Gamx, double *Gamy, double *Gamz,
|
||||
double *Lap, double *betax, double *betay, double *betaz,
|
||||
double *dtSfx, double *dtSfy, double *dtSfz,
|
||||
double *chi_rhs, double *trK_rhs,
|
||||
double *gxx_rhs, double *gxy_rhs, double *gxz_rhs, double *gyy_rhs, double *gyz_rhs, double *gzz_rhs,
|
||||
double *Axx_rhs, double *Axy_rhs, double *Axz_rhs, double *Ayy_rhs, double *Ayz_rhs, double *Azz_rhs,
|
||||
double *Gamx_rhs, double *Gamy_rhs, double *Gamz_rhs,
|
||||
double *Lap_rhs, double *betax_rhs, double *betay_rhs, double *betaz_rhs,
|
||||
double *dtSfx_rhs, double *dtSfy_rhs, double *dtSfz_rhs,
|
||||
double *rho, double *Sx, double *Sy, double *Sz,
|
||||
double *Sxx, double *Sxy, double *Sxz, double *Syy, double *Syz, double *Szz,
|
||||
double *Gamxxx, double *Gamxxy, double *Gamxxz, double *Gamxyy, double *Gamxyz, double *Gamxzz,
|
||||
double *Gamyxx, double *Gamyxy, double *Gamyxz, double *Gamyyy, double *Gamyyz, double *Gamyzz,
|
||||
double *Gamzxx, double *Gamzxy, double *Gamzxz, double *Gamzyy, double *Gamzyz, double *Gamzzz,
|
||||
double *Rxx, double *Rxy, double *Rxz, double *Ryy, double *Ryz, double *Rzz,
|
||||
double *ham_Res, double *movx_Res, double *movy_Res, double *movz_Res,
|
||||
double *Gmx_Res, double *Gmy_Res, double *Gmz_Res,
|
||||
int &Symmetry, int &Lev, double &eps, int &co);
|
||||
|
||||
@@ -104,6 +104,20 @@ int bssn_cuda_unpack_state_batch_from_host_buffer(void *block_tag,
|
||||
int i0, int j0, int k0,
|
||||
int sx, int sy, int sz);
|
||||
|
||||
int bssn_cuda_pack_state_batch_to_device_buffer(void *block_tag,
|
||||
int state_count,
|
||||
double *device_buffer,
|
||||
int *ex,
|
||||
int i0, int j0, int k0,
|
||||
int sx, int sy, int sz);
|
||||
|
||||
int bssn_cuda_unpack_state_batch_from_device_buffer(void *block_tag,
|
||||
int state_count,
|
||||
double *device_buffer,
|
||||
int *ex,
|
||||
int i0, int j0, int k0,
|
||||
int sx, int sy, int sz);
|
||||
|
||||
int bssn_cuda_download_state_subset(void *block_tag,
|
||||
int *ex,
|
||||
int subset_count,
|
||||
@@ -122,6 +136,6 @@ void bssn_cuda_release_step_ctx(void *block_tag);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user