#include <iostream>
#include <cuda_runtime.h>
#include <cuda_runtime_api.h>
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
#define HOST __host__
#define DEVICE __device__
template<class L>
__global__ void launch_global (L f0) { f0(); }
template<typename T>
struct Array{
T* __restrict__ data;
DEVICE HOST inline
T& operator()(int i)const noexcept {
return data[i];
}
};
int main(){
int nx = 5;
auto vec = Array<double>{new double[nx]};
Array<double> *vec1;
cudaMallocManaged((void**)&vec1, nx * sizeof(double));
launch_global<<<1,256>>>([=] DEVICE () noexcept{
int i = blockDim.x*blockIdx.x+threadIdx.x;
if(i < nx){
(*vec1)(i) = 1.0;
printf("Printing here %d %g\n", i,1.0);
}
});
cudaDeviceSynchronize();
return 0;
}
编译:
nvcc -x cu --expt-extended-lambda --expt-relaxed-constexpr --expt-relaxed-constexpr kernel_test.cpp -o out
问题:
问题是print语句- printf(“Printing here %d %g\n”,i,1.0)没有被执行。但是如果我注解上一行- vec(i)=1.0,那么print命令就会执行。有人能帮我弄清楚为什么吗?
我也试过运行cuda-memcheck。没有错误。
1条答案
按热度按时间c3frrgcw1#
存在各种问题。
首先,这个:
通过使用
new
创建一个分配的指针。无论您随后做什么,该指针***将永远无法在设备代码中使用***。这不是使用UM的正确策略。接下来,您的分配大小在这里没有意义:
vec1
是指向Array<double>
类型的指针。基于sizeof(double)
分配大小没有意义。如果你想使用UM(托管内存)来实现这一点,你将需要处理类对象的分配以及对象中嵌入指针的分配。
您通常会感到困惑,因为您正在分配一个
Array<double>
对象数组,每个对象都有一个指向double
项的嵌入式指针。下面的代码修复了这些问题,并且对我来说似乎可以正确运行: