• OpenACC 计算构建内的自定义函数


    ▶ 使用 routine 构件创建的自定义函数,在并行调用上的差别

    ● 代码,自定义一个 sqab 函数,使用内建函数 fabsf 和 sqrtf 计算一个矩阵所有元素绝对值的平方根

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <math.h>
     4 #include <openacc.h>
     5 
     6 #define ROW 8
     7 #define COL 64
     8 
     9 #pragma acc routine vector
    10 void sqab(float *a, const int m)
    11 {    
    12 #pragma acc loop
    13     for (int idx = 0; idx < m; idx++)
    14         a[idx] = sqrtf(fabsf(a[idx]));    
    15 }
    16 
    17 int main()
    18 {
    19     float x[ROW][COL];
    20     int row, col;
    21     for (row = 0; row < ROW; row++)
    22     {
    23         for (col = 0; col < COL; col++)
    24             x[row][col] = row * 10 + col;
    25     }
    26     printf("
    x[1][1] = %f
    ", x[1][1]);
    27 
    28 #pragma acc parallel loop vector pcopy(x[0:ROW][0:COL]) // 之后在这里分别添加 gang,worker,vector
    29     for (row = 0; row < ROW; row++)
    30         sqab(&x[row][0], COL);
    31     printf("
    x[1][1] = %f
    ", x[1][1]);
    32 
    33     //getchar();
    34     return 0;
    35 }

     ● 输出结果,第 28 行不添加并行级别子句(默认使用 gang)

     1 D:CodeOpenACCOpenACCProjectOpenACCProject>pgcc main.c -acc -Minfo -o main_acc.exe
     2 sqab:
     3      11, Generating Tesla code
     4          13, #pragma acc loop vector /* threadIdx.x */
     5      13, Loop is parallelizable
     6 main:
     7      28, Generating copy(x[:][:])
     8          Accelerator kernel generated
     9          Generating Tesla code
    10          29, #pragma acc loop gang /* blockIdx.x */
    11 
    12 D:CodeOpenACCOpenACCProjectOpenACCProject>main_acc.exe
    13 
    14 x[1][1] = 11.000000
    15 launch CUDA kernel  file=D:CodeOpenACCOpenACCProjectOpenACCProjectmain.c function=main
    16 line=28 device=0 threadid=1 num_gangs=8 num_workers=1 vector_length=32 grid=8 block=32      // 8 个 gang 在 blockIdx.x 层级,1 个 worker,vector 在 threadIdx.x 层级
    17 
    18 x[1][1] = 3.316625
    19 PGI: "acc_shutdown" not detected, performance results might be incomplete.
    20  Please add the call "acc_shutdown(acc_device_nvidia)" to the end of your application to ensure that the performance results are complete.
    21 
    22 Accelerator Kernel Timing data
    23 D:CodeOpenACCOpenACCProjectOpenACCProjectmain.c
    24   main  NVIDIA  devicenum=0
    25     time(us): 9
    26     28: compute region reached 1 time
    27         28: kernel launched 1 time
    28             grid: [8]  block: [32]
    29             elapsed time(us): total=1000 max=1000 min=1000 avg=1000
    30     28: data region reached 2 times
    31         28: data copyin transfers: 1
    32              device time(us): total=4 max=4 min=4 avg=4
    33         31: data copyout transfers: 1
    34              device time(us): total=5 max=5 min=5 avg=5

     ● 输出结果,第 28 行添加并行级别子句 worker

     1 D:CodeOpenACCOpenACCProjectOpenACCProject>pgcc main.c -acc -Minfo -o main_acc.exe
     2 sqab:
     3      11, Generating Tesla code
     4          13, #pragma acc loop vector /* threadIdx.x */
     5      13, Loop is parallelizable
     6 main:
     7      28, Generating copy(x[:][:])
     8          Accelerator kernel generated
     9          Generating Tesla code
    10          29, #pragma acc loop worker(4) /* threadIdx.y */
    11      29, Loop is parallelizable
    12 
    13 D:CodeOpenACCOpenACCProjectOpenACCProject>main_acc.exe
    14 
    15 x[1][1] = 11.000000
    16 launch CUDA kernel  file=D:CodeOpenACCOpenACCProjectOpenACCProjectmain.c function=main
    17 line=28 device=0 threadid=1 num_gangs=1 num_workers=4 vector_length=32 grid=1 block=32x4    // 1 个 gang,4 个 worker 在 threadIdx.y 层级,使用 2 维线程网格
    18 
    19 x[1][1] = 3.316625
    20 PGI: "acc_shutdown" not detected, performance results might be incomplete.
    21  Please add the call "acc_shutdown(acc_device_nvidia)" to the end of your application to ensure that the performance results are complete.
    22 
    23 Accelerator Kernel Timing data
    24 D:CodeOpenACCOpenACCProjectOpenACCProjectmain.c
    25   main  NVIDIA  devicenum=0
    26     time(us): 10
    27     28: compute region reached 1 time
    28         28: kernel launched 1 time
    29             grid: [1]  block: [32x4]
    30              device time(us): total=0 max=0 min=0 avg=0
    31     28: data region reached 2 times
    32         28: data copyin transfers: 1
    33              device time(us): total=5 max=5 min=5 avg=5
    34         31: data copyout transfers: 1
    35              device time(us): total=5 max=5 min=5 avg=5

     ● 输出结果,第 28 行添加并行级别子句 vector

     1 D:CodeOpenACCOpenACCProjectOpenACCProject>pgcc main.c -acc -Minfo -o main_acc.exe
     2 sqab:
     3      11, Generating Tesla code
     4          13, #pragma acc loop vector /* threadIdx.x */
     5      13, Loop is parallelizable
     6 main:
     7      28, Generating copy(x[:][:])
     8          Accelerator kernel generated
     9          Generating Tesla code
    10          29, #pragma acc loop seq
    11      29, Loop is parallelizable
    12 
    13 D:CodeOpenACCOpenACCProjectOpenACCProject>main_acc.exe
    14 
    15 x[1][1] = 11.000000
    16 launch CUDA kernel  file=D:CodeOpenACCOpenACCProjectOpenACCProjectmain.c function=main 
    17 line=28 device=0 threadid=1 num_gangs=1 num_workers=1 vector_length=32 grid=1 block=32      // 1 个 gang,1 个 worker,并行全都堆在 threadIdx.x 层级上
    18 
    19 x[1][1] = 3.316625
    20 PGI: "acc_shutdown" not detected, performance results might be incomplete.
    21  Please add the call "acc_shutdown(acc_device_nvidia)" to the end of your application to ensure that the performance results are complete.
    22 
    23 Accelerator Kernel Timing data
    24 D:CodeOpenACCOpenACCProjectOpenACCProjectmain.c
    25   main  NVIDIA  devicenum=0
    26     time(us): 10
    27     28: compute region reached 1 time
    28         28: kernel launched 1 time
    29             grid: [1]  block: [32]
    30             elapsed time(us): total=1000 max=1000 min=1000 avg=1000
    31     28: data region reached 2 times
    32         28: data copyin transfers: 1
    33              device time(us): total=5 max=5 min=5 avg=5
    34         31: data copyout transfers: 1
    35              device time(us): total=5 max=5 min=5 avg=5

    ● 如果自定义函数并行子句等级高于主调函数,则主调函数并行子句会变成 seq;如果自定义函数并行子句等级低于内部并行子句等级,则会报 warning,忽略掉内部并行子句:

    1 #pragma acc routine vector
    2 void sqab(float *a, const int m)
    3 {    
    4 #pragma acc loop worker
    5     for (int idx = 0; idx < m; idx++)
    6         a[idx] = sqrtf(fabsf(a[idx]));    
    7 }

    ● 编译结果(运行结果通上面的 worker,不写)

    D:CodeOpenACCOpenACCProjectOpenACCProject>pgcc main.c -acc -Minfo -o main_acc.exe
    PGC-W-0155-acc loop worker clause ignored in acc routine vector procedure  (main.c: 13)
    sqab:
         11, Generating Tesla code
             13, #pragma acc loop vector /* threadIdx.x */
         13, Loop is parallelizable
  • 相关阅读:
    无废话MVC入门教程五[Control与View交互]
    无废话MVC入门教程三[路由设置及视图入门]
    无废话MVC入门教程二[第一个小Demo]
    IDEA 插件开发
    慢慢学Linux驱动开发,第十章,GNU C的扩展
    《UNIX环境高级编程》编译问题彻底解决方案
    GNU make笔记
    outlook2003无法显示地址列表 无法打开与该地址列表的相关"联系人"文件夹解决方案
    慢慢学Linux驱动开发,第十二章,加入内核
    ADS: (Fatal)L6002U:Could not open file:..... & L6002
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/9419372.html
Copyright © 2020-2023  润新知