1 of 9

GPU PROGRAMMING FOR BEGINNERS

2 of 9

WHY PROGRAM ON GPUS

  • CPUs are designed for serial tasks
    • Typically 1-8 high clock cores
    • Can execute sequential instructions fast
  • GPUs are designed for parallel tasks
    • 100s to 1000s of cores
    • Designed to divide load across cores
    • Higher latency

https://www.heavy.ai/technical-glossary/cpu-vs-gpu

3 of 9

VISUAL DEMONSTRATION

4 of 9

WHAT IS OPENACC

  • It is a compiler addon that parallelizes existing code
    • Simple to use
    • Little modifications necessary
    • Offloads parallelizable code to GPUs
  • Free compiler available
    • https://www.pgroup.com/products/community.htm
    • Example usage: pgcc -fast -ta=tesla:cc60 -Minfo=accel -o laplace laplace.c

main() {

<serial code>

#pragma acc kernels {

<parallel code>

}

}

5 of 9

PREPROCESSOR/COMPILER DIRECTIVES

  • Not real code
  • Directives for the preprocessor
    • i.e macros: #define identifier replacement
  • Modifies code before compilation
  • OpenACC Preprocessor Directives
    • Generates code compatible for GPU
    • Parallelizes it and splits it up
    • Handles CPU to GPU memory transfer

https://www.geeksforgeeks.org/cc-preprocessors/

6 of 9

EXAMPLE

  • Compute a*x + y, where x and y are vectors, and a is a scalar

int main(int argc, char **argv){ int N=1000;� float a = 3.0f;� float x[N], y[N];

for (int i = 0; i < N; ++i) { x[i] = 2.0f;� y[i] = 1.0f;

}

#pragma acc kernels

for (int i = 0; i < N; ++i) {

y[i] = a * x[i] + y[i];

}

}

7 of 9

EXAMPLE

while ( error > tol && iter < iter_max ) {

    error = 0.f;

 

    #pragma omp parallel for shared(m, n, Anew, A)

    for( int j = 1; j < n-1; j++) {

        for( int i = 1; i < m-1; i++ ) {

            Anew[j][i] = 0.25f * ( A[j][i+1] + A[j][i-1]

                                 + A[j-1][i] + A[j+1][i]);

            error = fmaxf( error, fabsf(Anew[j][i]-A[j][i]));

        }

    }

 

    #pragma omp parallel for shared(m, n, Anew, A)

    for( int j = 0; j < n-1; j++) {

        for( int i = 0; i < m-1; i++ ) {

            A[j][i] = Anew[j][i];   

        }

    }

 

    if(iter % 100 == 0) printf("%d, %0.6fn", iter, error);

 

    iter++;

}

  • Jacobi Iteration

https://developer.nvidia.com/blog/openacc-example-part-1/

8 of 9

RUN YOUR CODE

    • Compile as you normally would
    • Example: pgcc -fast -ta=tesla:cc60 -Minfo=accel -o jacobi jacobi.c
    • Run as normal

9 of 9

OTHER RESOURCES