Visual studio Can';t将vec3作为参数传递给CUDA内核

Visual studio Can';t将vec3作为参数传递给CUDA内核,visual-studio,cuda,nvidia,glm-math,Visual Studio,Cuda,Nvidia,Glm Math,我对CUDA非常陌生,我一直在尝试制作一个简单的光线跟踪器,但我遇到了一个奇怪的问题,将glm::vec3变量传递到内核实际上并没有复制我想要的vec3的值。 当我使用#define GLM_FORCE_CUDA时,我收到一条奇怪的错误消息说“GLM需要CUDA 7.0或更高版本”,因此我跟踪了该错误,显然nvcc没有定义CUDA版本,所以我添加了一个 在我的文件中包含,这似乎可以消除错误,但我仍然认为我的问题与此有关,因为我尝试将glm::vec3发送到另一个项目中的内核,但没有问题。 无论如

我对CUDA非常陌生,我一直在尝试制作一个简单的光线跟踪器,但我遇到了一个奇怪的问题,将glm::vec3变量传递到内核实际上并没有复制我想要的vec3的值。 当我使用#define GLM_FORCE_CUDA时,我收到一条奇怪的错误消息说“GLM需要CUDA 7.0或更高版本”,因此我跟踪了该错误,显然nvcc没有定义CUDA版本,所以我添加了一个
在我的文件中包含
,这似乎可以消除错误,但我仍然认为我的问题与此有关,因为我尝试将glm::vec3发送到另一个项目中的内核,但没有问题。 无论如何,内核是这样的:

__global__ void render(unsigned char* pix_buff_loc, int max_x, int max_y, glm::vec3 lower_left_corner, glm::vec3 horizontal, glm::vec3 vertical, glm::vec3 origin) {
    int i = threadIdx.x + blockIdx.x * blockDim.x;
    int j = threadIdx.y + blockIdx.y * blockDim.y;
    if ((i >= max_x) || (j >= max_y)) return;
    int pixel_index = j * max_x * 4 + i * 4;
    float u = i / max_x;
    float v = j / max_y;
    ray r1(origin, lower_left_corner + u * horizontal + v * vertical);
    vec3 dir = glm::normalize(r1.get_direction());
    float t = 0.5f * (dir.y + 1.0f);
    vec3 col = (float)(1.0 - t) * vec3(1.0, 1.0, 1.0) + t * vec3(0.5, 0.7, 1.0);
    unsigned char r = (int)(255 * col.x);
    unsigned char g = (int)(255 * col.y);
    unsigned char b = (int)(255 * col.z);
    vec3 v1(1750, 0, 255);
    pix_buff_loc[pixel_index + 0] = (int)v1.x;
    pix_buff_loc[pixel_index + 1] = (int)v1.y;
    pix_buff_loc[pixel_index + 2] = (int)v1.z;
    pix_buff_loc[pixel_index + 3] = 255;
}
glm::vec3 lower_left_corner(-2.f, -1.f, -1.f);
    glm::vec3 horizontal(4.f, 0.f, 0.f);
    glm::vec3 vertical(0.f, 2.f, 0.f);
    glm::vec3 origin(0.f, 0.f, 0.f);
    render << <blocks, threads >> > (out_data, width, height, lower_left_corner, horizontal, vertical, origin); 
下面是我如何称呼内核的:

__global__ void render(unsigned char* pix_buff_loc, int max_x, int max_y, glm::vec3 lower_left_corner, glm::vec3 horizontal, glm::vec3 vertical, glm::vec3 origin) {
    int i = threadIdx.x + blockIdx.x * blockDim.x;
    int j = threadIdx.y + blockIdx.y * blockDim.y;
    if ((i >= max_x) || (j >= max_y)) return;
    int pixel_index = j * max_x * 4 + i * 4;
    float u = i / max_x;
    float v = j / max_y;
    ray r1(origin, lower_left_corner + u * horizontal + v * vertical);
    vec3 dir = glm::normalize(r1.get_direction());
    float t = 0.5f * (dir.y + 1.0f);
    vec3 col = (float)(1.0 - t) * vec3(1.0, 1.0, 1.0) + t * vec3(0.5, 0.7, 1.0);
    unsigned char r = (int)(255 * col.x);
    unsigned char g = (int)(255 * col.y);
    unsigned char b = (int)(255 * col.z);
    vec3 v1(1750, 0, 255);
    pix_buff_loc[pixel_index + 0] = (int)v1.x;
    pix_buff_loc[pixel_index + 1] = (int)v1.y;
    pix_buff_loc[pixel_index + 2] = (int)v1.z;
    pix_buff_loc[pixel_index + 3] = 255;
}
glm::vec3 lower_left_corner(-2.f, -1.f, -1.f);
    glm::vec3 horizontal(4.f, 0.f, 0.f);
    glm::vec3 vertical(0.f, 2.f, 0.f);
    glm::vec3 origin(0.f, 0.f, 0.f);
    render << <blocks, threads >> > (out_data, width, height, lower_left_corner, horizontal, vertical, origin); 
glm::vec3左下角(-2.f,-1.f,-1.f);
glm::vec3水平(4.f,0.f,0.f);
垂直(0.f,2.f,0.f);
glm::vec3原点(0.f,0.f,0.f);
渲染>(输出数据、宽度、高度、左下角、水平、垂直、原点);
我在内核中放置了一个断点,以使用nsight调试器检查值,下面是我得到的结果:


另外,我不知道这是否相关,但是,ray类构造函数有一个
\uuuu设备\uuuu
说明符,因此我在项目的属性中启用了可重定位代码。构建输出中没有错误消息,那么我哪里出了问题?

我刚下载了最新版本的glm,这次我没有将文件包括在我的项目中,问题消失了

你能发布一个其他人可以编译和测试的实际版本吗?基于一些代码片段和一些东西的图像,很难说会发生什么(请不要发布图像,它们不会被未来的访问者搜索到)嘿,谢谢你的建议,不幸的是,我无法在另一个测试中重现这个问题,但是,我可以通过在主机和设备之间对所有4个vec3参数执行cudaMemcpy,然后在内核中使用指针访问它们来规避这个问题。目前它还可以正常工作,但我仍然无法找出之前出现的错误(考虑到第一个方法在另一个虽然简单得多的项目中实际如何工作)。你真的确定它能正确地处理这些类型吗?是的,glm::vec3构造函数同时具有设备和主机declspec,但我不认为在这里调用构造函数来创建副本,在这种情况下,问题将是vec3类的cpu和gpu上的布局冲突,但是另一种使用cudamemcpy的方法也不应该起作用,但是它确实起作用了,现在我不知道如果你把一个类作为参数传递,那么会发生什么,然后使用复制构造。这是cuda对内核参数支持的唯一习惯用法