From a88644cb9a61f010e6fad21bf688bde85d0e7dfe Mon Sep 17 00:00:00 2001 From: George Zagaris Date: Fri, 24 Sep 2021 17:14:36 -0400 Subject: [PATCH 1/4] ENH: add NVTX annotations to UpdateFringes --- src/LocalMesh.C | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/LocalMesh.C b/src/LocalMesh.C index 386312d..4f134ca 100644 --- a/src/LocalMesh.C +++ b/src/LocalMesh.C @@ -337,10 +337,16 @@ void LocalMesh::UpdateFringes(double *qh, double *qd) // doesn't work CUDA-Aware -- debug this void LocalMesh::UpdateFringes(double *qd) { + FVSAND_NVTX_FUNCTION("UpdateFringes"); + nthreads=device2host.size(); if(nthreads == 0) return; - FVSAND_GPU_KERNEL_LAUNCH( updateHost, nthreads, - qbuf_d,qd,device2host_d,nthreads); + + FVSAND_NVTX_SECTION( "pack", + FVSAND_GPU_KERNEL_LAUNCH( updateHost, nthreads, + qbuf_d,qd,device2host_d,nthreads); + ); + // separate sends and receives so that we can overlap comm and calculation // in the residual and iteration loops. // TODO (george) use qbuf2_d and qbuf_d instead of qbuf2 and qbuf for cuda-aware @@ -348,16 +354,26 @@ void LocalMesh::UpdateFringes(double *qd) pc.postRecvs_direct(qbuf2,nfields_d,rcvmap,ireq,mycomm,&reqcount); // TODO (george) with cuda-aware this pull is not required // but it doesn't work now - gpu::pull_from_device(qbuf,qbuf_d,sizeof(double)*device2host.size()); + FVSAND_NVTX_SECTION( "copy-to-host", + gpu::pull_from_device( qbuf, qbuf_d, sizeof(double)*device2host.size() ); + ); + pc.postSends_direct(qbuf,nfields_d,sndmap,ireq,mycomm,&reqcount); pc.finish_comm(reqcount,ireq,istatus); + // same as above // not doing cuda-aware now - gpu::copy_to_device(qbuf_d2,qbuf2,sizeof(double)*host2device.size()); - + FVSAND_NVTX_SECTION( "copy-to-device", + gpu::copy_to_device( qbuf_d2, qbuf2, sizeof(double)*host2device.size() ); + ); + nthreads=host2device.size(); - FVSAND_GPU_KERNEL_LAUNCH( updateDevice, nthreads, - qd,qbuf_d2,host2device_d,nthreads); + + FVSAND_NVTX_SECTION( "unpack", + FVSAND_GPU_KERNEL_LAUNCH( updateDevice, nthreads, + qd,qbuf_d2,host2device_d,nthreads ); + ); + } From 038edfe2ffcd1ec2487a58daa19159487819bce3 Mon Sep 17 00:00:00 2001 From: George Zagaris Date: Sun, 26 Sep 2021 13:01:30 -0400 Subject: [PATCH 2/4] ENH: comment out Tecplot I/O for mesh partitions --- src/fvsand.C | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fvsand.C b/src/fvsand.C index e55af82..23a563d 100644 --- a/src/fvsand.C +++ b/src/fvsand.C @@ -143,7 +143,7 @@ int main(int argc, char *argv[]) printf("# ----------------------------------\n"); } - lm->WriteMesh(myid); + // lm->WriteMesh(myid); MPI_Finalize(); From 15fb777e559ca1897a149e6868d20f5f9f33fc75 Mon Sep 17 00:00:00 2001 From: George Zagaris Date: Sun, 26 Sep 2021 15:37:56 -0400 Subject: [PATCH 3/4] ENH: methods to alloc/dealloc host-pinned memory --- src/fvsand_cuda.h | 15 +++++++++++++++ src/fvsand_hip.h | 17 +++++++++++++++++ src/fvsand_nogpu.h | 13 +++++++++++++ 3 files changed, 45 insertions(+) diff --git a/src/fvsand_cuda.h b/src/fvsand_cuda.h index 93dd174..c15e0ba 100644 --- a/src/fvsand_cuda.h +++ b/src/fvsand_cuda.h @@ -47,6 +47,14 @@ inline T* allocate_on_device(const size_t size) return dptr; } +template +inline T* allocate_host_pinned(const size_t size) +{ + T* dptr = nullptr; + FVSAND_CUDA_CHECK_ERROR(cudaHostAlloc((void**)(&dptr), size,cudaHostAllocMapped)); + return dptr; +} + template inline void copy_to_device(T* dptr, const T* hptr, const size_t size) { @@ -74,6 +82,13 @@ inline void deallocate_device(T** dptr) *dptr = nullptr; } +template +inline void deallocate_host_pinned(T** ptr) +{ + FVSAND_CUDA_CHECK_ERROR(cudaFreeHost(static_cast(*ptr))); + *ptr = nullptr; +} + template inline void memset_on_device(T* dptr, T val, const size_t sz) { diff --git a/src/fvsand_hip.h b/src/fvsand_hip.h index b9f3084..df854c9 100644 --- a/src/fvsand_hip.h +++ b/src/fvsand_hip.h @@ -48,6 +48,15 @@ inline T* allocate_on_device(const size_t size) return dptr; } +template +inline T* allocate_host_pinned(const size_t size) +{ + T* dptr = nullptr; + FVSAND_CUDA_CHECK_ERROR(hipHostMalloc((void**)(&dptr), size)); + return dptr; +} + + template inline void copy_to_device(T* dptr, const T* hptr, const size_t size) { @@ -75,6 +84,14 @@ inline void deallocate_device(T** dptr) *dptr = nullptr; } +template < typename T> +inline void deallocate_host_pinned(T** ptr) +{ + FVSAND_CUDA_CHECK_ERROR(hipHostFree(static_cast(*ptr))); + *ptr = nullptr; +} + + template inline void memset_on_device(T* dptr, T val, const size_t sz) { diff --git a/src/fvsand_nogpu.h b/src/fvsand_nogpu.h index 9b12be5..09c10e7 100644 --- a/src/fvsand_nogpu.h +++ b/src/fvsand_nogpu.h @@ -27,6 +27,12 @@ inline T* allocate_on_device(const size_t size) return static_cast(std::malloc(size)); } +template +inline T* allocate_host_pinned(const size_t size) +{ + return static_cast(std::malloc(size)); +} + template inline void copy_to_device(T* dptr, const T* hptr, const size_t size) { @@ -54,6 +60,13 @@ inline void deallocate_device(T** dptr) *dptr = nullptr; } +template < typename T> +inline void deallocate_host_pinned(T** ptr) +{ + std::free(*ptr); + *ptr = nullptr; +} + template inline void memset_on_device(T* dptr, T val, const size_t sz) { From b6bba0eaf0c15a53aa3b0e4d508de40871bb0d43 Mon Sep 17 00:00:00 2001 From: George Zagaris Date: Sun, 26 Sep 2021 15:51:11 -0400 Subject: [PATCH 4/4] ENH: use host-pinned mapped memory Uses host-pinned mapped memory, which alleviates the need for copying the data from host-to-device in UpdateFringes. --- src/LocalMesh.C | 41 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/src/LocalMesh.C b/src/LocalMesh.C index 4f134ca..a5fb55e 100644 --- a/src/LocalMesh.C +++ b/src/LocalMesh.C @@ -22,10 +22,10 @@ LocalMesh::~LocalMesh() FVSAND_FREE_DEVICE(device2host_d); FVSAND_FREE_DEVICE(host2device_d); // - if (qbuf) delete [] qbuf; - if (qbuf2) delete [] qbuf2; - FVSAND_FREE_DEVICE(qbuf_d); - FVSAND_FREE_DEVICE(qbuf_d2); + gpu::deallocate_host_pinned(&qbuf); + gpu::deallocate_host_pinned(&qbuf2); + gpu::deallocate_host_pinned(&qbuf_d); + gpu::deallocate_host_pinned(&qbuf_d2); // FVSAND_FREE_DEVICE(x_d); FVSAND_FREE_DEVICE(flovar_d); @@ -41,7 +41,7 @@ LocalMesh::~LocalMesh() FVSAND_FREE_DEVICE(center_d); FVSAND_FREE_DEVICE(normals_d); FVSAND_FREE_DEVICE(volume_d); - FVSAND_FREE_DEVICE(res_d); + gpu::deallocate_host_pinned(&res_d); // FVSAND_FREE_DEVICE(rmatall_d); FVSAND_FREE_DEVICE(Dall_d); @@ -60,7 +60,7 @@ LocalMesh::~LocalMesh() FVSAND_FREE_DEVICE(q); FVSAND_FREE_DEVICE(qn); FVSAND_FREE_DEVICE(qnn); - FVSAND_FREE_DEVICE(dq_d); + gpu::deallocate_host_pinned(&dq_d); FVSAND_FREE_DEVICE(dqupdate_d); } @@ -256,8 +256,8 @@ void LocalMesh::InitSolution(double *flovar, int nfields) q=gpu::allocate_on_device(sizeof(double)*(ncells+nhalo)*nfields); qn=gpu::allocate_on_device(sizeof(double)*(ncells+nhalo)*nfields); qnn=gpu::allocate_on_device(sizeof(double)*(ncells+nhalo)*nfields); - res_d=gpu::allocate_on_device(sizeof(double)*(ncells+nhalo)*nfields); - dq_d=gpu::allocate_on_device(sizeof(double)*(ncells+nhalo)*nfields); + res_d=gpu::allocate_host_pinned(sizeof(double)*(ncells+nhalo)*nfields); + dq_d=gpu::allocate_host_pinned(sizeof(double)*(ncells+nhalo)*nfields); dqupdate_d=gpu::allocate_on_device(sizeof(double)*(ncells+nhalo)*nfields); ); @@ -291,10 +291,10 @@ void LocalMesh::InitSolution(double *flovar, int nfields) int dsize=device2host.size(); dsize=(dsize < host2device.size())?host2device.size():dsize; - qbuf=new double [dsize]; - qbuf2=new double [dsize]; - qbuf_d=gpu::allocate_on_device(sizeof(double)*dsize); - qbuf_d2=gpu::allocate_on_device(sizeof(double)*dsize); + qbuf=gpu::allocate_host_pinned(sizeof(double)*dsize); + qbuf2=gpu::allocate_host_pinned(sizeof(double)*dsize); + qbuf_d=gpu::allocate_host_pinned(sizeof(double)*dsize); + qbuf_d2=gpu::allocate_host_pinned(sizeof(double)*dsize); ireq=new MPI_Request [sndmap.size()+rcvmap.size()]; istatus=new MPI_Status [sndmap.size()+rcvmap.size()]; @@ -352,26 +352,15 @@ void LocalMesh::UpdateFringes(double *qd) // TODO (george) use qbuf2_d and qbuf_d instead of qbuf2 and qbuf for cuda-aware int reqcount=0; pc.postRecvs_direct(qbuf2,nfields_d,rcvmap,ireq,mycomm,&reqcount); - // TODO (george) with cuda-aware this pull is not required - // but it doesn't work now - FVSAND_NVTX_SECTION( "copy-to-host", - gpu::pull_from_device( qbuf, qbuf_d, sizeof(double)*device2host.size() ); - ); - pc.postSends_direct(qbuf,nfields_d,sndmap,ireq,mycomm,&reqcount); + gpu::synchronize(); + pc.postSends_direct(qbuf_d,nfields_d,sndmap,ireq,mycomm,&reqcount); pc.finish_comm(reqcount,ireq,istatus); - - // same as above - // not doing cuda-aware now - FVSAND_NVTX_SECTION( "copy-to-device", - gpu::copy_to_device( qbuf_d2, qbuf2, sizeof(double)*host2device.size() ); - ); nthreads=host2device.size(); - FVSAND_NVTX_SECTION( "unpack", FVSAND_GPU_KERNEL_LAUNCH( updateDevice, nthreads, - qd,qbuf_d2,host2device_d,nthreads ); + qd,qbuf2,host2device_d,nthreads ); ); }