我有一个这样定义的结构:
typedef struct Data_{
double **v;
.
.
.
double *press;
}Data;
在主函数中,我有一个while循环,其中它被称为一个例程,其中声明了数据,并且我使用了以下的杂注:
static Data data;
#pragma acc enter data copyin(data[:7])
在这个例程中,它被称为另一个( RHS (&data, ...)
)。同样,在后者中,我调用另一个例程( RHS1(data,...)
),其中有一个我想加速的循环:
#pragma acc parallel loop present(data[:7])
for (i = beg; i <= end; i++) {
rhs[i][MX1] += dt*data->src[i][MX1];
. += .
. += .
. += .
. += .
. += .
rhs[i][ENG] += dt*sweep->src[i][ENG];
}
使用-managed:致命错误:变量数据子句编译此错误,设备: name=data中部分显示了此错误。
发布于 2020-07-17 18:06:27
这里有几个问题。
#pragma acc enter data copyin(data[:7])
这意味着您希望复制一个由7个“数据”结构组成的数组,而不是一个包含7个成员的结构。将其改为:
#pragma acc enter data copyin(data)
编译器知道结构的大小,并将在设备副本中分配适当的大小。
但是,copy子句只执行结构的浅拷贝。因此,在这里,您要将数据成员的主机指针复制到设备上,访问"src“将给您提供一个非法的地址错误。因此,您需要采取额外步骤,对设备上将要使用的所有成员进行手动深度复制。
因此,在程序的后面,在分配"src“之后,添加一个附加指令:
#pragma acc enter data copyin(data.src[0:nx][0:ny])
(将nx和ny更改为尺寸的实际大小变量)
这将首先在设备上创建" src“数组,然后将设备src”附加“到数据的设备副本。“附加”基本上是将设备"data.src“的值填充到设备src数组的地址。
然后,在并行循环中,只使用“出现(数据)”。
注意,如果使用update指令同步数据,请确保只更新"src“而不是" data”。同样,这将执行一个浅拷贝,以便更新数据将复制主机/设备指针,这将导致运行时错误。
作为“使用OpenACC并行编程”一书第5章的一部分,我编写了一个关于如何这样做的基本示例,您可以在以下站点找到这个示例:https://github.com/rmfarber/ParallelProgrammingWithOpenACC/blob/master/Chapter05/array_of_structs.c。
https://stackoverflow.com/questions/62950868
复制相似问题