我目前正在研究openacc API
,我想知道是否有可能在设备上创建一个阵列而主机上没有任何相应的分配数组。
假设我想使用旧的cuda kernel
,并且只通过openacc API
处理内存管理。我需要一些仅在设备上使用的256个元素的数组。如果我只是在没有分配的情况下在主机上声明我的指针,它们可能有顺序地址。
如果我在这些指针上使用present_or_create
子句,我的大小为256个元素,那么我会在设备上以不同的数组结束吗?
或者主机上的连续地址,加上我的数组的长度,将被视为同一阵列的一部分?
这是一个例子:指针A的地址是0,指针B的地址是4。
如果我在pcreate
和A[0:256]
上执行了两次B[0:256]
,由于主机上的数据范围为[0 , 1024]
和[4 , 1028]
,我是否会结束设备上有两个不同的256个元素阵列,或者我最终只有一个范围为[0 , 1028]
的数组?
我是否必须首先在主机上分配我的两个数组以确保有两个不同的数组,或者此方法是否可以正常工作?
答案 0 :(得分:2)
我真的只能和PGI的实现交谈,但我认为Cray的工作方式与此类似。创建/复制/存在数据子句键入主机数据的地址,以确定数据是否已存在于设备上。如果指针A和指针B碰巧具有相同的值(都指向相同的空间),则pcreate(A [0:256],B [0:256])将为A创建数据,那么B的present_or_测试将看到数据已经存在。如果主机上的A [0]到A [255]与B [0]到B [255]重叠,则运行时也会看到重叠。重要的不是起始地址,而是整个范围。该模型用于在设备上创建数据,该数据是主机上相同数据的镜像,“当前表”查找的“关键字”是主机地址范围。
在您的特定情况下,如果指针A的值为0,那么这是一个NULL指针并且处理方式不同。因此,如果指针A的值为4,B的值为8并且执行pcreate(A [0:256],B [0:256]),则会为A复制[4:256],然后运行时会注意到你试图移动一个重叠但不包含在现有空间内的B范围。这在规范中是不允许的,我们的编译器不支持。支持这将需要在设备上重新分配A的数据,这可能意味着设备地址将移动。由于可以捕获这些地址,并且旧陈旧地址将不再起作用,因此这是不安全的事情。