OpenACC 存在子句更新数据
OpenACC present clause update data
我正在尝试为许多身体模拟进行openACC优化。目前,我面临一个导致以下内存问题的问题
调用
cuStreamSynchronize
返回错误 700:内核执行
期间地址非法 调用cuMemFreeHost
返回错误 700:内核执行
期间地址非法srun
:错误:jrc0017:任务 0:退出,退出代码为 1
我正在使用pgc++
编译器,我的编译器标志-acc -Minfo=accel -ta=tesla -fast -std=c++11
,我不想使用-ta=tesla:managed
,因为我想自己组织内存。
#pragma acc kernels present(sim.part.rx, sim.part.ry, sim.part.rz, sim.part.vx, sim.part.vy, sim.part.vz)
{
for(int idx = 0; idx < sim.num; ++idx) { // Loop over target particle
float
prx = sim.part.rx[idx], // my position
pry = sim.part.ry[idx],
prz = sim.part.rz[idx];
float Fx = 0.f, Fy = 0.f, Fz = 0.f; // Force
#pragma acc loop
for(int jdx = 0; jdx < sim.num; ++jdx) { // Loop over interaction partners
if(idx != jdx) { // No self-force
const float dx = prx - sim.part.rx[jdx]; // Distance to partner
const float dy = pry - sim.part.ry[jdx];
const float dz = prz - sim.part.rz[jdx];
const float h = 1.f/sqrt(dx*dx + dy*dy + dz*dz + eps);
const float h3 = h*h*h;
Fx += dx*h3; // Sum up force
Fy += dy*h3;
Fz += dz*h3;
}
}
sim.part.vx[idx] += sim.mass*dt*Fx; // update velocity
sim.part.vy[idx] += sim.mass*dt*Fy;
sim.part.vz[idx] += sim.mass*dt*Fz;
}
}
如果我删除下面的代码
sim.part.vx[idx] += sim.mass*dt*Fx; // update velocity
sim.part.vy[idx] += sim.mass*dt*Fy;
sim.part.vz[idx] += sim.mass*dt*Fz;
我的代码能够毫无问题地运行。但是如果我取消评论它们,我会遇到记忆问题。似乎sim.part.vx
尝试更新数据,但编译器不知道哪个导致内存问题。
有谁知道如何解决这个问题?
我怀疑问题是sim
和sim.part
不在设备上(或者编译器没有意识到它们在设备上。作为一种解决方法,您可以尝试直接引入指向这些数组的指针吗?
float *rx = sim.part.rx, *ry = sim.part.ry, *rz = sim.part.rz,
*vx = sim.part.vx, *vy = sim.part.vy, *vz = sim.part.vz;
#pragma acc kernels present(rx, ry, rz, vx, vy, vz)
{
for(int idx = 0; idx < sim.num; ++idx) { // Loop over target particle
float
prx = rx[idx], // my position
pry = ry[idx],
prz = rz[idx];
float Fx = 0.f, Fy = 0.f, Fz = 0.f; // Force
#pragma acc loop
for(int jdx = 0; jdx < sim.num; ++jdx) { // Loop over interaction partners
if(idx != jdx) { // No self-force
const float dx = prx - rx[jdx]; // Distance to partner
const float dy = pry - ry[jdx];
const float dz = prz - rz[jdx];
const float h = 1.f/sqrt(dx*dx + dy*dy + dz*dz + eps);
const float h3 = h*h*h;
Fx += dx*h3; // Sum up force
Fy += dy*h3;
Fz += dz*h3;
}
}
vx[idx] += sim.mass*dt*Fx; // update velocity
vy[idx] += sim.mass*dt*Fy;
vz[idx] += sim.mass*dt*Fz;
}
}
sim 和 sim.part 是如何分配的?可以在构造函数和析构函数中使用非结构化数据指令,以确保 sim 和 sim.part 也在设备上。如果您已经这样做了,那么另一种可能的解决方案是将present(sim, sim.part)
添加到现有的 present 子句中,以便编译器知道您也已经处理了这些数据结构。
相关文章:
- 如何在ECS框架中更新组件数据和通知系统
- 在 1 个服务器 n 客户端套接字 C++ MFC 应用程序中更新数据的客户端
- LLVM:在运行时更新数据结构
- 类的成员数据未更新
- 使用二进制数据更新 PostgreSQL 表
- QTableView 不会更新数据
- 有没有办法有效地更新QML中的CAN数据?
- 如何使用C++删除/更新txt文件中的特定数据
- 如何使用C++删除/更新txt文件中的特定数据?
- 比较 JSON::Value 变量中的数据,然后更新到文件
- 如何自动更新表格数据或数据库
- 如何在线程中更新qcustomplot数据
- 从高度动态的C 数据模型中更新QML:计时器与属性绑定
- 随着C 的数据更改,更新本地Qlabel的文本
- 用于在具有更新查询的二维矩阵中查找最大值的最佳数据结构
- MySQL 使用一组列中的数据更新列,以非零值为准
- 使用来自不同线程的实时数据更新QTableView的最佳策略
- 从网站将数据更新到QTableView(间歇性)
- 如何使用 ODBC API 将数据更新插入到 NVARCHAR 列中
- OpenGL + 无法使用缓冲区子数据更新缓冲区数据