为什么我在此代码中得到 Present table dump for device[1]: NVIDIA Tesla GPU 0?

Why I get Present table dump for device[1]: NVIDIA Tesla GPU 0 in this code?

这是头文件DataHolder.h:

#ifndef DATAHOLDER_H
#define DATAHOLDER_H
using FloatingType=float;
int LIFE=0;
const int GL=2000000;
template <typename Floating> class DataHolder {
public:
  Floating particles[GL];
public:
  DataHolder(){}
 ~DataHolder(){}
 void Propagate();
 void InitParticle();
 };
template <typename Floating> void DataHolder<Floating>::Propagate()
{
#pragma acc parallel loop copy(LIFE) present(particles)
  for(int i=0; i<LIFE; ++i) Floating r0= particles[i];
}
template <typename Floating> void DataHolder<Floating>::InitParticle()
{
#pragma acc parallel num_gangs(1) vector_length(1) 
present(particles[0:GL]) copy(LIFE)
{
  particles[LIFE]=0.0f;
#pragma acc atomic update
  ++LIFE;
}
}
#endif//DATAHOLDER_H

我在文件中使用它main.cpp:

#include <iostream>
#include "DataHolder.h"
#include <accelmath.h>
#include <openacc.h>
#include <cuda.h>
#include <cuda_runtime.h>
int main(int argc, char **argv)
{
  DataHolder<FloatingType> * d;
  cudaMalloc((void**) & d, sizeof(DataHolder<FloatingType>));
  std::cout<<"sizeof(DataHolder<FloatingType>)=" 
  <<sizeof(DataHolder<FloatingType>)/1024/1024<<" MB"<<std::endl;  
  LIFE=0;
  int step=0;
  d->InitParticle();
  cudaFree(d);
}

程序编译,但失败:

sizeof(DataHolder)=7 MB hostptr=0x501520000,stride=1,size=2000000,eltsize=4,flags=0x200=present,async=-1,threadid=1 Present table dump for device[1]: NVIDIA Tesla GPU 0, compute capability 3.0, threadid=1 host:0x604b60 device:0x501ce0000 size:4 presentcount:1+0 line:26 name:LIFE allocated block device:0x501ce0000 size:512 thread:1 FATAL ERROR: data in PRESENT clause was not found on device 1: name=(null) host:0x501520000 file:/home/70-gaa/NFbuild_script_CHECK_GPU/ERROR/T3DataHolder.h _ZN10DataHolderIfE12InitParticleEv line:26

为什么?怎么了?

我使用以下编译行编译在 GPU GeForce GTX 650 Ti 上启动的代码:

cmake . -DCMAKE_C_COMPILER=pgcc -DCMAKE_CXX_COMPILER=pgc++ - 
DCMAKE_CXX_FLAGS="-acc -mcmodel=medium =ta=tesla:cc30,managed -fast - 
Mcuda=cuda10.1 --c++11"

使用 PGI 19.4 C++ 编译器、gcc 5.3.1、OS Fedora 23 x86_64、CUDA 10.1、CUDA 驱动程序版本 418.67。

"present" 子句检查设备上是否存在特定变量,但只能检查由 OpenACC 运行时管理的变量。在这里,您通过运行时不管理的 cudaMalloc 分配数据。在这些情况下,您应该将 "present" 替换为 "deviceptr" 以告知运行时这是一个 CUDA 设备指针。您需要添加 "this" 指针,因为它也是一个设备指针。

但是,由于您取消引用 "d" 这不是有效的主机指针,因此您的代码将在主机上出现段错误。

这里最简单的解决方案是不使用 cudaMalloc 并使用 "new" 分配 "d"。由于您使用的是 CUDA 统一内存,"d" 的数据移动将由 CUDA 驱动程序处理。