如何使用OpenACC在C中执行结构的2D动态数组的手动深度复制

阿里·伊姆兰

我正在尝试使用OpenACC修改现有的粒子方法代码以在GPU上运行。现有代码利用c中struct的2D动态数组。我需要将结构复制到GPU进行进一步的计算。下面是一个代码示例:

typedef struct{
  int *list;  // it is list of particles in a given bucket
  int  count; // it is the total number of particles in the bucket
} structBucket;


typedef struct{
structBucket  **bucket;
int    numberOfBuckets[2]; // number of buckets in x- and y- dimensions
} structDomain;

structDomain domain;

// Allocate memory for **bucket
  domain.numberOfBuckets[XDIM] = 10; domain.numberOfBuckets[YDIM] = 5;
  int iX,iY, capacity;

  domain.bucket = (structBucket**)malloc( sizeof(structBucket*) * domain.numberOfBuckets[XDIM] );

   for (iX=0 ; iX < domain.numberOfBuckets[XDIM] ; iX++) 
      domain.bucket[iX] = (structBucket*)malloc( sizeof(structBucket) * domain.numberOfBuckets[YDIM]);

// Calculate domain.bucket[iX][iY].count here using some logic
.
.
.
// Allocate memory for *list
  for (iX = 0; iX < domain.numberOfBuckets[XDIM]; iX++)
  {
    for (iY = 0; iY < domain.numberOfBuckets[YDIM]; iY++)
    {
        capacity = domain.bucket[iX][iY].count;

        if (capacity > 0)
        {
          domain.bucket[iX][iY].list = (int *)malloc(sizeof(int) * capacity);
        }
    }
  }

在回顾了互联网上的各种来源之后,我提出了以下解决方案(可能完全错误)”

// It is needed to create the memory for **bucket and *list on GPU. 
#pragma acc enter data copyin(domain)
#pragma acc enter data copyin(domain.bucket)
#pragma acc enter data create(domain.bucket[0:domain.numberOfBuckets[XDIM]][0:domain.numberOfBuckets[YDIM]])
  for (iX = 0; iX < domain.numberOfBuckets[XDIM]; iX++)
  {
    for (iY = 0; iY < domain.numberOfBuckets[YDIM]; iY++)
    {
        #pragma acc enter data create(domain.bucket[iX][iY].list[0:domain.bucket[iX][iY].count])
    }
  }

要求将** bucket和* list深度复制到GPU内存的建议手册。我的解决方案准确吗?有人可以建议对所述结构进行手动深拷贝的改进或更好的解决方案。

我在Windows 10上使用PGI 19.4编译器。非常感谢

马特·科格罗夫

关。我唯一要做的就是不要创建“ domain.bucket”并更新存储桶的计数,以便设备具有此信息。另外,由于更新/副本比较浅,因此请确保仅更新结构中的列表数组或标量。否则,您可能会覆盖设备/主机指针。这是一个例子。当我使用Linux时,除了可执行文件名称外,代码应该相同。

% cat test.c

#include <stdio.h>
#include <stdlib.h>

typedef struct{
  int *list;  // it is list of particles in a given bucket
  int  count; // it is the total number of particles in the bucket
} structBucket;


typedef struct{
structBucket  **bucket;
int    numberOfBuckets[2]; // number of buckets in x- and y- dimensions
} structDomain;

#define XDIM 64
#define YDIM 64

int main() {

  structDomain domain;
  int iX,iY, capacity;

// Allocate memory for **bucket
  domain.numberOfBuckets[XDIM] = 10; domain.numberOfBuckets[YDIM] = 5;

  domain.bucket = (structBucket**)malloc( sizeof(structBucket*) * domain.numberOfBuckets[XDIM] );

   for (iX=0 ; iX < domain.numberOfBuckets[XDIM] ; iX++)
      domain.bucket[iX] = (structBucket*)malloc( sizeof(structBucket) * domain.numberOfBuckets[YDIM]);


// Calculate domain.bucket[iX][iY].count here using some logic
  for (iX = 0; iX < domain.numberOfBuckets[XDIM]; iX++)
  {
    for (iY = 0; iY < domain.numberOfBuckets[YDIM]; iY++)
    {
       domain.bucket[iX][iY].count = iX*domain.numberOfBuckets[YDIM]+iY;
  }}
#pragma acc enter data copyin(domain)
#pragma acc enter data create(domain.bucket[:domain.numberOfBuckets[XDIM]][:domain.numberOfBuckets[YDIM]])
// Allocate memory for *list
  for (iX = 0; iX < domain.numberOfBuckets[XDIM]; iX++)
  {
    for (iY = 0; iY < domain.numberOfBuckets[YDIM]; iY++)
    {
        capacity = domain.bucket[iX][iY].count;
#pragma acc update device(domain.bucket[iX][iY].count)
        if (capacity > 0)
        {
          domain.bucket[iX][iY].list = (int *)malloc(sizeof(int) * capacity);
#pragma acc enter data create(domain.bucket[iX][iY].list[:capacity])
        }
    }
  }

#pragma acc parallel loop gang collapse(2) present(domain)
  for (iX = 0; iX < domain.numberOfBuckets[XDIM]; iX++)
  {
    for (iY = 0; iY < domain.numberOfBuckets[YDIM]; iY++)
    {
        capacity = domain.bucket[iX][iY].count;
        if (capacity > 0) {
#pragma acc loop vector
           for (int i = 0; i < capacity; ++i) {
                domain.bucket[iX][iY].list[i] = i;
           }
        }
   }}

  for (iX = 0; iX < 5; iX++)
  {
    for (iY = 0; iY < 5; iY++)
    {
        capacity = domain.bucket[iX][iY].count;
        if (capacity > 0) {
#pragma acc update host(domain.bucket[iX][iY].list[:capacity])
           printf("iX=%d iY=%d Cnt=%d\n\t",iX,iY,capacity);
           for (int i = 0; i < capacity; ++i) {
                printf("%d ",domain.bucket[iX][iY].list[i]);
           }
           printf("\n");
        }
   }}

  exit(0);
}
% pgcc test.c -ta=tesla -Minfo=accel -V19.4
main:
     40, Generating enter data copyin(domain)
     41, Generating enter data create(domain.bucket[:domain.numberOfBuckets][:domain.numberOfBuckets])
     49, Generating update device(domain.bucket->->count)
     52, Generating enter data create(domain.bucket->->list[:capacity])
     57, Generating present(domain)
         Generating Tesla code
         58, #pragma acc loop gang collapse(2) /* blockIdx.x */
         60,   /* blockIdx.x collapsed */
         65, #pragma acc loop vector(128) /* threadIdx.x */
     65, Accelerator restriction: size of the GPU copy of domain.bucket is unknown
         Loop is parallelizable
     78, Generating update self(domain.bucket->->list[:capacity])
% a.out
iX=0 iY=1 Cnt=1
        0
iX=0 iY=2 Cnt=2
        0 1
iX=0 iY=3 Cnt=3
        0 1 2
iX=0 iY=4 Cnt=4
        0 1 2 3
iX=1 iY=0 Cnt=5
        0 1 2 3 4
iX=1 iY=1 Cnt=6
        0 1 2 3 4 5
iX=1 iY=2 Cnt=7
        0 1 2 3 4 5 6
iX=1 iY=3 Cnt=8
        0 1 2 3 4 5 6 7
iX=1 iY=4 Cnt=9
        0 1 2 3 4 5 6 7 8
iX=2 iY=0 Cnt=10
        0 1 2 3 4 5 6 7 8 9
iX=2 iY=1 Cnt=11
        0 1 2 3 4 5 6 7 8 9 10
iX=2 iY=2 Cnt=12
        0 1 2 3 4 5 6 7 8 9 10 11
iX=2 iY=3 Cnt=13
        0 1 2 3 4 5 6 7 8 9 10 11 12
iX=2 iY=4 Cnt=14
        0 1 2 3 4 5 6 7 8 9 10 11 12 13
iX=3 iY=0 Cnt=15
        0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
iX=3 iY=1 Cnt=16
        0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
iX=3 iY=2 Cnt=17
        0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
iX=3 iY=3 Cnt=18
        0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
iX=3 iY=4 Cnt=19
        0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
iX=4 iY=0 Cnt=20
        0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
iX=4 iY=1 Cnt=21
        0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
iX=4 iY=2 Cnt=22
        0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
iX=4 iY=3 Cnt=23
        0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
iX=4 iY=4 Cnt=24
        0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在C中手动深度复制到设备

来自分类Dev

使用C中的char数组进行深度复制结构(如何复制数组?)

来自分类Dev

如何在C#中手动使用资源(不执行IDE操作)?

来自分类Dev

手动遍历c中的数组

来自分类Dev

如何在C中填充2D结构数组?

来自分类Dev

在Moodle中手动复制文件

来自分类Dev

如何对结构的2D动态数组进行排序

来自分类Dev

如何在JavaScript中手动写出3D数组

来自分类Dev

如何在char []数组中手动输入字符?

来自分类Dev

C在手动填充的数组中搜索值

来自分类Dev

C在手动填充的数组中搜索值

来自分类Dev

String.substring()的性能与手动查找复制到char []数组中的性能相比如何?

来自分类Dev

如何在Rust中的结构内实现动态2D数组?

来自分类Dev

如何在C中手动迭代堆栈帧?

来自分类Dev

如何在Visual C ++中手动处理名称?

来自分类Dev

如何手动编译使用C ++的Cython代码?

来自分类Dev

如何使用symfony2和主义从数据库中手动查询

来自分类Dev

几个C#项目如何在没有繁琐的手动复制的情况下使用非托管DLL?

来自分类Dev

尝试在C中复制4个char结构的2D数组时出现memcpy错误分段错误

来自分类Dev

如何在C中的结构的指针成员中存储2d数组的内存地址

来自分类Dev

如何在C#Unity中将C结构与2D数组一起使用

来自分类Dev

在C#中复制2D数组

来自分类Dev

C中结构(2d数组)的静态成员(2d数组)

来自分类Dev

如何使用路径攀登rpart对象的树形结构以手动清除某些节点?

来自分类Dev

在C ++ 14中手动实现结构化绑定

来自分类Dev

如何在C中的动态2D字符数组中查找行数?

来自分类Dev

如何在C ++中访问2D动态数组中的1个元素

来自分类Dev

在Android中手动复制sqlite数据库

来自分类Dev

在android中手动复制sqlite数据库

Related 相关文章

  1. 1

    在C中手动深度复制到设备

  2. 2

    使用C中的char数组进行深度复制结构(如何复制数组?)

  3. 3

    如何在C#中手动使用资源(不执行IDE操作)?

  4. 4

    手动遍历c中的数组

  5. 5

    如何在C中填充2D结构数组?

  6. 6

    在Moodle中手动复制文件

  7. 7

    如何对结构的2D动态数组进行排序

  8. 8

    如何在JavaScript中手动写出3D数组

  9. 9

    如何在char []数组中手动输入字符?

  10. 10

    C在手动填充的数组中搜索值

  11. 11

    C在手动填充的数组中搜索值

  12. 12

    String.substring()的性能与手动查找复制到char []数组中的性能相比如何?

  13. 13

    如何在Rust中的结构内实现动态2D数组?

  14. 14

    如何在C中手动迭代堆栈帧?

  15. 15

    如何在Visual C ++中手动处理名称?

  16. 16

    如何手动编译使用C ++的Cython代码?

  17. 17

    如何使用symfony2和主义从数据库中手动查询

  18. 18

    几个C#项目如何在没有繁琐的手动复制的情况下使用非托管DLL?

  19. 19

    尝试在C中复制4个char结构的2D数组时出现memcpy错误分段错误

  20. 20

    如何在C中的结构的指针成员中存储2d数组的内存地址

  21. 21

    如何在C#Unity中将C结构与2D数组一起使用

  22. 22

    在C#中复制2D数组

  23. 23

    C中结构(2d数组)的静态成员(2d数组)

  24. 24

    如何使用路径攀登rpart对象的树形结构以手动清除某些节点?

  25. 25

    在C ++ 14中手动实现结构化绑定

  26. 26

    如何在C中的动态2D字符数组中查找行数?

  27. 27

    如何在C ++中访问2D动态数组中的1个元素

  28. 28

    在Android中手动复制sqlite数据库

  29. 29

    在android中手动复制sqlite数据库

热门标签

归档