gpudirect, cuda aware mpi, & cuda ipc€¦ · steve abbott, february 12, 2019 gpudirect, cuda...

42
Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI, & CUDA IPC

Upload: others

Post on 20-May-2020

49 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

Steve Abbott, February 12, 2019

GPUDIRECT, CUDA AWARE MPI,

& CUDA IPC

Page 2: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

2

AGENDAWhat is GPU Direct?CUDA Aware MPIAdvanced On Node Communication

Page 3: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

3

GPUDIRECT

Page 4: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

4

NVIDIA GPUDIRECT™Accelerated Communication with Network & Storage Devices

2/12/2

019

GPU1

GPU1

Memory

PCI-e/NVLINK

CPU

Chip

set

System

Memory

GPU2

GPU2

Memory

IB

Page 5: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

5

NVIDIA GPUDIRECT™Peer to Peer Transfers

2/12/2

019

GPU1

GPU1

Memory

CPU

Chip

set

GPU2

GPU2

Memory

IB

System

Memory

PCI-e/NVLINK

Page 6: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

6

NVIDIA GPUDIRECT™Support for RDMA

2/12/2

019

GPU1

GPU1

Memory

CPU

Chip

set

GPU2

GPU2

Memory

IB

System

Memory

PCI-e/NVLINK

Page 7: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

7

CUDA AWARE MPI FOR ON AND OFF NODE TRANSFERS

Page 8: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

8

REGULAR MPI GPU TO REMOTE GPU

cudaMemcpy(s_buf_h,s_buf_d,size,cudaMemcpyDeviceToHost);

MPI_Send(s_buf_h,size,MPI_CHAR,1,tag,MPI_COMM_WORLD);

MPI_Recv(r_buf_h,size,MPI_CHAR,0,tag,MPI_COMM_WORLD,&stat);

cudaMemcpy(r_buf_d,r_buf_h,size,cudaMemcpyHostToDevice);

cudaMemcpy(s_buf_h,s_buf_d,size,cudaMemcpyDeviceToHost);

MPI_Send(s_buf_h,size,MPI_CHAR,1,tag,MPI_COMM_WORLD);

MPI_Recv(r_buf_h,size,MPI_CHAR,0,tag,MPI_COMM_WORLD,&stat);

cudaMemcpy(r_buf_d,r_buf_h,size,cudaMemcpyHostToDevice);

cudaMemcpy(s_buf_h,s_buf_d,size,cudaMemcpyDeviceToHost);

MPI_Send(s_buf_h,size,MPI_CHAR,1,tag,MPI_COMM_WORLD);

MPI_Recv(r_buf_h,size,MPI_CHAR,0,tag,MPI_COMM_WORLD,&stat);

cudaMemcpy(r_buf_d,r_buf_h,size,cudaMemcpyHostToDevice);

cudaMemcpy(s_buf_h,s_buf_d,size,cudaMemcpyDeviceToHost);

MPI_Send(s_buf_h,size,MPI_CHAR,1,tag,MPI_COMM_WORLD);

MPI_Recv(r_buf_h,size,MPI_CHAR,0,tag,MPI_COMM_WORLD,&stat);

cudaMemcpy(r_buf_d,r_buf_h,size,cudaMemcpyHostToDevice);

cudaMemcpy(s_buf_h,s_buf_d,size,cudaMemcpyDeviceToHost);

MPI_Send(s_buf_h,size,MPI_CHAR,1,tag,MPI_COMM_WORLD);

MPI_Recv(r_buf_h,size,MPI_CHAR,0,tag,MPI_COMM_WORLD,&stat);

cudaMemcpy(r_buf_d,r_buf_h,size,cudaMemcpyHostToDevice);

MPI Rank 0 MPI Rank 1

GPU

Host

Page 9: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

9

REGULAR MPI GPU TO REMOTE GPU

2/12/2

019

memcpy H->DMPI_Sendrecvmemcpy D->H

Time

Page 10: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

10

MPI GPU TO REMOTE GPUwithout GPUDirect

MPI_Send(s_buf_d,size,MPI_CHAR,1,tag,MPI_COMM_WORLD);

MPI_Recv(r_buf_d,size,MPI_CHAR,0,tag,MPI_COMM_WORLD,&stat);

MPI_Send(s_buf_d,size,MPI_CHAR,1,tag,MPI_COMM_WORLD);

MPI_Recv(r_buf_d,size,MPI_CHAR,0,tag,MPI_COMM_WORLD,&stat);

MPI_Send(s_buf_d,size,MPI_CHAR,1,tag,MPI_COMM_WORLD);

MPI_Recv(r_buf_d,size,MPI_CHAR,0,tag,MPI_COMM_WORLD,&stat);

MPI Rank 0 MPI Rank 1

GPU

Host

Page 11: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

11

MPI GPU TO REMOTE GPUwithout GPUDirect

MPI_Send(s_buf_d,size,MPI_CHAR,1,tag,MPI_COMM_WORLD);

MPI_Recv(r_buf_d,size,MPI_CHAR,0,tag,MPI_COMM_WORLD,&stat);

MPI_Send(s_buf_d,size,MPI_CHAR,1,tag,MPI_COMM_WORLD);

MPI_Recv(r_buf_d,size,MPI_CHAR,0,tag,MPI_COMM_WORLD,&stat);

#pragma acc host_data use_device (s_buf, r_buf)

MPI_Send(s_buf,size,MPI_CHAR,1,tag,MPI_COMM_WORLD);

MPI_Recv(r_buf,size,MPI_CHAR,0,tag,MPI_COMM_WORLD,&stat);

MPI Rank 0 MPI Rank 1

GPU

Host

Page 12: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

12

MPI GPU TO REMOTE GPUwithout GPUDirect

2/12/2

019

MPI_Sendrecv

Time

Page 13: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

13

MPI GPU TO REMOTE GPUSupport for RDMA

MPI Rank 0 MPI Rank 1

GPU

Host

MPI_Send(s_buf_d,size,MPI_CHAR,1,tag,MPI_COMM_WORLD);

MPI_Recv(r_buf_d,size,MPI_CHAR,0,tag,MPI_COMM_WORLD,&stat);

MPI_Send(s_buf_d,size,MPI_CHAR,1,tag,MPI_COMM_WORLD);

MPI_Recv(r_buf_d,size,MPI_CHAR,0,tag,MPI_COMM_WORLD,&stat);

MPI_Send(s_buf_d,size,MPI_CHAR,1,tag,MPI_COMM_WORLD);

MPI_Recv(r_buf_d,size,MPI_CHAR,0,tag,MPI_COMM_WORLD,&stat);

Page 14: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

14

MPI GPU TO REMOTE GPUSupport for RDMA

MPI Rank 0 MPI Rank 1

GPU

Host

MPI_Send(s_buf_d,size,MPI_CHAR,1,tag,MPI_COMM_WORLD);

MPI_Recv(r_buf_d,size,MPI_CHAR,0,tag,MPI_COMM_WORLD,&stat);

MPI_Send(s_buf_d,size,MPI_CHAR,1,tag,MPI_COMM_WORLD);

MPI_Recv(r_buf_d,size,MPI_CHAR,0,tag,MPI_COMM_WORLD,&stat);

#pragma acc host_data use_device (s_buf, r_buf)

MPI_Send(s_buf,size,MPI_CHAR,1,tag,MPI_COMM_WORLD);

MPI_Recv(r_buf,size,MPI_CHAR,0,tag,MPI_COMM_WORLD,&stat);

Page 15: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

15

MPI GPU TO REMOTE GPUSupport for RDMA

2/12/2

019

Time

MPI_Sendrecv

Page 16: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

16

ADVANCED ON-NODE COMMUNICATION

Page 17: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

17

UNDER THE HOOD

Many connections

Many devices

Many stacks

Summit has fat nodes!

Page 18: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

18

SINGLE THREADED MULTI GPU PROGRAMMINGwhile ( l2_norm > tol && iter < iter_max ) {

for ( int dev_id = 0; dev_id < num_devices; ++dev_id ) {

const int top = dev_id > 0 ? dev_id - 1 : (num_devices-1); const int bottom = (dev_id+1)%num_devices;

cudaSetDevice( dev_id );

cudaMemsetAsync(l2_norm_d[dev_id], 0 , sizeof(real) );

jacobi_kernel<<<dim_grid,dim_block>>>( a_new[dev_id], a[dev_id], l2_norm_d[dev_id],

iy_start[dev_id], iy_end[dev_id], nx );

cudaMemcpyAsync( l2_norm_h[dev_id], l2_norm_d[dev_id], sizeof(real), cudaMemcpyDeviceToHost );

cudaMemcpyAsync( a_new[top]+(iy_end[top]*nx), a_new[dev_id]+iy_start[dev_id]*nx, nx*sizeof(real), ...);

cudaMemcpyAsync( a_new[bottom], a_new[dev_id]+(iy_end[dev_id]-1)*nx, nx*sizeof(real), ...);

}

l2_norm = 0.0;

for ( int dev_id = 0; dev_id < num_devices; ++dev_id ) {

cudaSetDevice( dev_id ); cudaDeviceSynchronize();

l2_norm += *(l2_norm_h[dev_id]);

}

l2_norm = std::sqrt( l2_norm );

for ( int dev_id = 0; dev_id < num_devices; ++dev_id ) std::swap(a_new[dev_id],a[dev_id]);

iter++;

}

Page 19: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

19

GPUDIRECT P2P

for ( int dev_id = 0; dev_id < num_devices; ++dev_id ) {

cudaSetDevice( dev_id );

const int top = dev_id > 0 ? dev_id - 1 : (num_devices-1);

int canAccessPeer = 0;

cudaDeviceCanAccessPeer ( &canAccessPeer, dev_id, top );

if ( canAccessPeer )

cudaDeviceEnablePeerAccess ( top, 0 );

const int bottom = (dev_id+1)%num_devices;

if ( top != bottom ) {

cudaDeviceCanAccessPeer ( &canAccessPeer, dev_id, bottom );

if ( canAccessPeer )

cudaDeviceEnablePeerAccess ( bottom, 0 );

}

}

Enable P2P

Page 20: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

20

EXAMPLE JACOBITop/Bottom Halo

cudaMemcpyAsync(

a_new[top]+(iy_end[top]*nx),

a_new[dev_id]+iy_start[dev_id]*nx, nx*sizeof(real), ...);

Page 21: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

21

EXAMPLE JACOBITop/Bottom Halo

1cudaMemcpyAsync(

a_new[top]+(iy_end[top]*nx),

a_new[dev_id]+iy_start[dev_id]*nx, nx*sizeof(real), ...);

1

Page 22: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

22

EXAMPLE JACOBITop/Bottom Halo

1

12

2cudaMemcpyAsync(

a_new[top]+(iy_end[top]*nx),

a_new[dev_id]+iy_start[dev_id]*nx, nx*sizeof(real), ...);

cudaMemcpyAsync(

a_new[bottom],

a_new[dev_id]+(iy_end[dev_id]-1)*nx, nx*sizeof(real), ...);

cudaMemcpyAsync(

a_new[top]+(iy_end[top]*nx),

a_new[dev_id]+iy_start[dev_id]*nx, nx*sizeof(real), ...);

Page 23: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

23

MULTIPLE PROCESS, SINGLE GPU W/O MPI!while ( l2_norm > tol && iter < iter_max ) {

const int top = dev_id > 0 ? dev_id - 1 : (num_devices-1); const int bottom = (dev_id+1)%num_devices;

cudaSetDevice( dev_id );

cudaMemsetAsync(l2_norm_d[dev_id], 0 , sizeof(real) );

jacobi_kernel<<<dim_grid,dim_block>>>( a_new[dev_id], a[dev_id], l2_norm_d[dev_id],

iy_start[dev_id], iy_end[dev_id], nx );

cudaMemcpyAsync( l2_norm_h[dev_id], l2_norm_d[dev_id], sizeof(real), cudaMemcpyDeviceToHost );

cudaMemcpyAsync( a_new[top]+(iy_end[top]*nx), a_new[dev_id]+iy_start[dev_id]*nx, nx*sizeof(real), ...);

cudaMemcpyAsync( a_new[bottom], a_new[dev_id]+(iy_end[dev_id]-1)*nx, nx*sizeof(real), ...);

l2_norm = 0.0;

for ( int dev_id = 0; dev_id < num_devices; ++dev_id ) {

l2_norm += *(l2_norm_h[dev_id]);

}

l2_norm = std::sqrt( l2_norm );

std::swap(a_new[dev_id],a[dev_id]);

iter++;

}

Page 24: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

24

GPUDIRECT P2P

cudaSetDevice( dev_id );

// Allocate and fill my device buffer

cudaMalloc((void **) &myBuf, nbytes);

cudaMemcpy((void *) myBuf, (void*) buf, nbytes, cudaMemcpyHostToDevice);

// Get my IPC handle

cudaIpcMemHandle_t myIpc;

cudaIpcGetMemHandle(&myIpc, myBuf);

Enable CUDA Inter-Process Communication (IPC)!

Page 25: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

25

GPUDIRECT P2P

cudaSetDevice( dev_id );

// Allocate and fill my device buffer

cudaMalloc((void **) &myBuf, nbytes);

cudaMemcpy((void *) myBuf, (void*) buf, nbytes, cudaMemcpyHostToDevice);

// Get my IPC handle

cudaIpcMemHandle_t myIpc;

cudaIpcGetMemHandle(&myIpc, myBuf);

Enable CUDA Inter-Process Communication (IPC)!

myBuf

Page 26: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

26

GPUDIRECT P2P

cudaSetDevice( dev_id );

// Allocate and fill my device buffer

cudaMalloc((void **) &myBuf, nbytes);

cudaMemcpy((void *) myBuf, (void*) buf, nbytes, cudaMemcpyHostToDevice);

// Get my IPC handle

cudaIpcMemHandle_t myIpc;

cudaIpcGetMemHandle(&myIpc, myBuf);

Enable CUDA Inter-Process Communication (IPC)!

myBuf myBuf

Page 27: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

27

GPUDIRECT P2P

cudaSetDevice( dev_id );

// Allocate and fill my device buffer

cudaMalloc((void **) &myBuf, nbytes);

cudaMemcpy((void *) myBuf, (void*) buf, nbytes, cudaMemcpyHostToDevice);

// Get my IPC handle

cudaIpcMemHandle_t myIpc;

cudaIpcGetMemHandle(&myIpc, myBuf);

Enable CUDA Inter-Process Communication (IPC)!

myBuf myBuf

Process 1

Process 2

Process 3

Page 28: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

28

GPUDIRECT P2P

cudaSetDevice( dev_id );

// Allocate and fill my device buffer

cudaMalloc((void **) &myBuf, nbytes);

cudaMemcpy((void *) myBuf, (void*) buf, nbytes, cudaMemcpyHostToDevice);

// Get my IPC handle

cudaIpcMemHandle_t myIpc;

cudaIpcGetMemHandle(&myIpc, myBuf);

Enable CUDA Inter-Process Communication (IPC)!

myBuf myBuf

Process 1

Process 2

Process 3

Page 29: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

29

EXAMPLE JACOBITop/Bottom Halo

// Open their Ipc Handle onto a pointer

cudaIpcOpenMemHandle((void **) &a_new[top], topIpc,

cudaIpcMemLazyEnablePeerAccess); cudaCheckError();

cudaMemcpyAsync(

a_new[top]+(iy_end[top]*nx),

a_new[dev_id]+iy_start[dev_id]*nx, nx*sizeof(real), ...);

Page 30: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

30

EXAMPLE JACOBITop/Bottom Halo

1

cudaIpcOpenMemHandle((void **) &a_new[top], topIpc,

cudaIpcMemLazyEnablePeerAccess); cudaCheckError();

cudaMemcpyAsync(

a_new[top]+(iy_end[top]*nx),

a_new[dev_id]+iy_start[dev_id]*nx, nx*sizeof(real), ...);

1

Page 31: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

31

EXAMPLE JACOBITop/Bottom Halo

1

12

2cudaMemcpyAsync(

a_new[top]+(iy_end[top]*nx),

a_new[dev_id]+iy_start[dev_id]*nx, nx*sizeof(real), ...);

cudaIpcOpenMemHandle((void **) &a_new[bottom], bottomIpc,

cudaIpcMemLazyEnablePeerAccess); cudaCheckError();

cudaMemcpyAsync(

a_new[bottom],

a_new[dev_id]+(iy_end[dev_id]-1)*nx, nx*sizeof(real), ...);

cudaIpcOpenMemHandle((void **) &a_new[top], topIpc,

cudaIpcMemLazyEnablePeerAccess); cudaCheckError();

cudaMemcpyAsync(

a_new[top]+(iy_end[top]*nx),

a_new[dev_id]+iy_start[dev_id]*nx, nx*sizeof(real), ...);

Page 32: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

32

GPU TO GPU COMMUNICATION

CUDA aware MPI functionally portable

OpenACC/MP interoperable

Performance may vary between on/off node, socket, HW support for GPU Direct

Unified memory support varies between implementations, but it becoming common

Single-process, multi-GPU

Enable peer access for straight forward on-node transfers

Multi-process, single-gpu

Pass CUDA IPC handles for on-node copies

Combine for more flexibility/complexity!

Page 33: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

33

ESSENTIAL TOOLS

Page 34: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

34

JSRUN/SMPI GPU OPTIONS

To enable CUDA aware MPI, use jsrun --smpiargs=“-gpu”

To run GPU code without MPI, use jsrun --smpiargs=“off”

Page 35: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

35

KNOWN ISSUES

No CUDA IPC across resource sets:

[1]Error opening IPC Memhandle from peer:0, invalid argument

One WAR: set PAMI_DISABLE_IPC=1

One (more complicated) WAR: bsub –step_cgroup n and

`swizzle`CUDA_VISIBLE_DEVICES [0,1,2] & [1,0,2] & [2,1,0]

Things to watch out for (as of December)

Page 36: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

36

CLOSING SUMMARY

Page 37: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

37

GPU TO GPU COMMUNICATION

CUDA aware MPI functionally portable

OpenACC/MP interoperable

Performance may vary between on/off node, socket, HW support for GPU Direct

WARNING: Unified memory support varies wildly between implementations!

Single-process, multi-GPU

Enable peer access for straight forward on-node transfers

Multi-process, single-gpu

Pass CUDA IPC handles for on-node copies

Combine for more flexibility/complexity!

Page 38: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

38

ESSENTIAL TOOLS AND TRICKS

Pick on-node layout with OLCF jsrun visualizer

https://jsrunvisualizer.olcf.ornl.gov/index.html

Select MPI/GPU interaction with jsrun --smpiargs

“-gpu” for CUDA aware, “off” for pure GPU without MPI

Profile MPI and NVLinks with nvprof

Good performance will require experimentation!

Page 39: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC
Page 40: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

40

SUMMIT NODE OVERVIEW

Page 41: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

41

CPU 0

256 GB (DDR4)

SUMMIT NODE(2) IBM POWER9 + (6) NVIDIA VOLTA V100

(50 GB/s)NVLink2

GPU 0 GPU 1 GPU 2

16 GB(HBM2)

16 GB(HBM2)

16 GB(HBM2)

0 (0-3)

8 (32-35)

16 (64-67)

1 (4-7)

9 (36-39)

17 (68-71)

2 (8-11)

10 (40-43)

18 (72-75)

3 (12-15)

11 (44-47)

19 (76-79)

4 (16-19)

12 (48-51)

20 (80-83)

5 (20-23)

13 (52-55)6 (24-27)

14 (56-59)7 (28-31)

15 (60-63)

CPU 1

256 GB (DDR4)

GPU 3 GPU 4 GPU 5

16 GB(HBM2)

16 GB(HBM2)

16 GB(HBM2)

22 (88-91)

30 (120-123)

38 (152-155)

23 (92-95)

31 (124-127)

39 (156-159)

24 (96-99)

32 (128-131)

40 (160-163)

25 (100-103)

33 (132-135)

41 (164-167)

26 (104-107)

34 (136-139)

42 (168-171)

27 (108-111)

35 (140-143)28 (112-115)

36 (144-147)29 (116-119)

37 (148-151)

64 GB/s

135 GB/s 135 GB/s

(900 GB/s)

Page 42: GPUDIRECT, CUDA AWARE MPI, & CUDA IPC€¦ · Steve Abbott, February 12, 2019 GPUDIRECT, CUDA AWARE MPI,& CUDA IPC

42

UNDER THE HOOD

Many connections

Many devices

Many stacks

Summit has fat nodes!