OpenACC Data Management Techniques
OpenACC Data Management Techniques
DATA MANAGEMENT
Speaker, Date
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
MODULE OVERVIEW
OpenACC Data Management
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
EXPLICIT MEMORY MANAGEMENT
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
EXPLICIT MEMORY MANAGEMENT
Requirements
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
EXPLICIT MEMORY MANAGEMENT
Key problems
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
EXPLICIT MEMORY MANAGEMENT device
CPU
Key problems
$ $ $ $ $ $
Shared Cache
devices) have a separate memory pool
from the host
$ $ $ $ $ $ $ $
different data
Transferring between these two memories
can be a very time consuming process CPU
Memory IO Bus
device
Memory
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
OPENACC DATA DIRECTIVE
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
OPENACC DATA DIRECTIVE
Definition
The data directive defines a lifetime #pragma acc data clauses
{
for data on the device
During the region data should be < Sequential and/or
thought of as residing on the Parallel code >
accelerator
}
Data clauses allow the programmer
to control the allocation and !$acc data clauses
movement of data
< Sequential and/or
Parallel code >
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
DATA CLAUSES
copy( list ) Allocates memory on device and copies data from host to device
when entering region and copies data to the host when exiting region.
Principal use: For many important data structures in your code, this is a
logical default to input, modify and return the data.
copyin( list ) Allocates memory on device and copies data from host to device
when entering region.
Principal use: Think of this like an array that you would use as just an
input to a subroutine.
copyout( list ) Allocates memory on device and copies data to the host when exiting
region.
Principal use: A result that isn’t overwriting the input data structure.
copy(array[starting_index:length]) C/C++
copy(array(starting_index:ending_inde
Fortran
x))
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
ARRAY SHAPING (CONT.)
Multi-dimensional Array shaping
copy(array[0:N][0:M]) C/C++
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
ARRAY SHAPING (CONT.)
Partial Arrays
copy(array[i*N/4:N/4]) C/C++
copy(array(i*N/4:i*N/4+N/4)) Fortran
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
STRUCTURED DATA DIRECTIVE
Example
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
STRUCTURED DATA DIRECTIVE
Example
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
STRUCTURED DATA DIRECTIVE
Example
#pragma acc data copyin(a[0:N],b[0:N])
copyout(c[0:N]) Action
{
#pragma acc parallel loop Deallocate
Execute
Allocate
Copy CA
Bloop
from
CA
B
C
A
B on
from
on
for(int i = 0; i < N; i++){ CPUdevice
device
totodevice
CPU
c[i] = a[i] + b[i];
}
}
A B C’
C A B C’
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
IMPLIED DATA REGIONS
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
IMPLIED DATA REGIONS
Definition
Every kernels and parallel region has
an implicit data region surrounding it
This allows data to exist solely for the #pragma acc kernels
duration of the region copyin(a[0:100])
{
All data clauses usable on a data for( int i = 0; i < 100; i+
+ )
directive can be used on a parallel and {
kernels as well a[i] = 0;
}
}
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
IMPLIED DATA REGIONS
Explicit vs Implicit Data Regions
Explicit Implicit
#pragma acc data copyin(a[0:100])
{
#pragma acc kernels
{ #pragma acc kernels copyin(a[0:100])
for( int i = 0; i < {
100; i++ ) for( int i = 0; i < 100; i++ )
{ {
a[i] = 0; a[i] = 0;
} }
} }
}
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
EXPLICIT VS. IMPLICIT DATA REGIONS
Limitation
The code on the left will perform better than the code on the right.
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
UNSTRUCTURED DATA DIRECTIVES
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
UNSTRUCTURED DATA DIRECTIVES
Enter Data Directive
Data lifetimes aren’t always neatly #pragma acc enter data clauses
structured.
The enter data directive handles < Sequential and/or
Parallel code >
device memory allocation
You may use either the create or the #pragma acc exit data clauses
copyin clause for memory allocation
!$acc enter data clauses
The enter data directive is not the start
of a data region, because you may < Sequential and/or
have multiple enter data directives Parallel code >
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
UNSTRUCTURED DATA DIRECTIVES
Exit Data Directive
The exit data directive handles device
memory deallocation #pragma acc enter data clauses
You may use either the delete or the < Sequential and/or
copyout clause for memory deallocation Parallel code >
You should have as many exit data for a #pragma acc exit data clauses
given array as enter data
These can exist in different functions !$acc enter data clauses
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
UNSTRUCTURED DATA CLAUSES
copyin ( list ) Allocates memory on device and copies data from host to device
on enter data.
copyout ( list ) Allocates memory on device and copies data back to the host on
exit data.
create ( list ) Allocates memory on device without data transfer on enter data.
delete ( list ) Deallocates memory on device without data transfer on exit data
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
UNSTRUCTURED DATA DIRECTIVES
Basic Example
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
UNSTRUCTURED DATA DIRECTIVES
Basic Example
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
UNSTRUCTURED DATA DIRECTIVES
Basic Example
C A B C’
A B C’ This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
UNSTRUCTURED DATA DIRECTIVES
Basic Example – proper memory deallocation
C A B
A B C’ This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
UNSTRUCTURED VS STRUCTURED
With a simple code
Unstructured Structured
Can have multiple starting/ending points Must have explicit start/end points
Can branch across multiple functions Must be within a single function
Memory exists until explicitly deallocated Memory only exists within the data region
#pragma acc enter data #pragma acc data copyin(a[0:N],b[0:N]) \
copyin(a[0:N],b[0:N]) \ create(c[0:N]) copyout(c[0:N])
{
#pragma acc parallel loop #pragma acc parallel loop
for(int i = 0; i < N; i++){ for(int i = 0; i < N; i++){
c[i] = a[i] + b[i]; c[i] = a[i] + b[i];
} }
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
UNSTRUCTURED DATA DIRECTIVES
Branching across multiple functions
int* allocate_array(int N){
int* ptr = (int *) malloc(N *
sizeof(int)); In this example enter data and exit data are
#pragma acc enter data
create(ptr[0:N]) in different functions
return ptr;
} This allows the programmer to put device
void deallocate_array(int* ptr){ allocation/deallocation with the matching
#pragma acc exit data delete(ptr) host versions
free(ptr);
}
This pattern is particularly useful in C++,
int main(){ where structured scopes may not be
int* a = allocate_array(100);
#pragma acc kernels possible.
{
a[0] = 0;
}
deallocate_array(a);
}
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
DATA SYNCHRONIZATION
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
OPENACC UPDATE DIRECTIVE
update: Explicitly transfers data between the host and the device
Useful when you want to synchronize data in the middle of a data region
Clauses:
self: makes host data agree with device data
device: makes device data agree with host data
B*
B B*
#pragma acc update self(A[0:N])
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
SYNCHRONIZE DATA WITH UPDATE
int* allocate_array(int N){
int* A=(int*)
malloc(N*sizeof(int)); Inside the initialize function we alter the
#pragma acc enter data
create(A[0:N]) host copy of ‘A’
return A;
} This means that after calling initialize the
host and device copy of ‘A’ are out-of-sync
void deallocate_array(int* A){
#pragma acc exit data We use the update directive with the
delete(A)
free(A); device clause to update the device copy of
} ‘A’
void initialize_array(int* A, int N){ Without the update directive later compute
for(int i = 0; i < N; i++){
A[i] = i;
regions will use incorrect data.
}
#pragma acc update
device(A[0:N])
}
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
C/C++ STRUCTS/CLASSES
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
C STRUCTS typedef struct {
Without dynamic data members float x, y, z;
} float3;
Dynamic data members are anything
int main(int argc, char* argv[]){
contained within a struct that can have int N = 10;
a variable size, such as dynamically float3* f3 = malloc(N *
allocated arrays sizeof(float3));
OpenACC is easily able to copy our #pragma acc enter data
struct to device memory because create(f3[0:N])
everything in our float3 struct has a
#pragma acc kernels
fixed size for(int i = 0; i < N; i++){
f3[i].x = 0.0f;
But what if the struct had dynamically f3[i].y = 0.0f;
allocated members? f3[i].z = 0.0f;
}
void accUpdateSelf() {
#pragma acc update self(arr[0:n])
}
void accUpdateDevice() {
#pragma acc update
device(arr[0:n])
}
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
USING A OPENACC AWARE C++ CLASS
#include “vector.h"
int main() { A A
vector A(N), B(N);
for (int i=0; i < [Link](); ++i) {
B[i]=2.5;
}
[Link](); B B
#pragma acc parallel loop present(A,B)
for (int i=0; i < [Link](); ++i) {
A[i]=B[i]+i;
}
[Link]();
for(int i=0; i<10; ++i) {
cout << "A[" << i << "]: " << A[i] << endl;
}
exit(0);
}
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
KEY CONCEPTS
In this module we discussed…
Why explicit data management is necessary for best performance
Structured and Unstructured Data Lifetimes
Explicit and Implicit Data Regions
The data, enter data, exit data, and update directives
Data Clauses
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
LAB ASSIGNMENT
In this module’s lab you will…
Update the code from the previous module to use explicit data
directives
Analyze the different between using CUDA Managed Memory and
explicit data management in the lab code.
This material is released by NVIDIA Corporation under the Creative Commons Attribution 4.0 International (CC BY 4.0)
ADDITIONAL RESOURCES
YouTube OpenACC Introduction Series by Michael Wolfe
Introduction to Parallel Programming with OpenACC – Part 5