【问题标题】:cudaMemcpyToSymbol use detailscudaMemcpyToSymbol 使用细节
【发布时间】:2013-11-07 21:38:33
【问题描述】:

我正在尝试将数据结构从主机移动到 Tesla C1060(计算 1.3)上的常量内存。具有以下功能:

//mem.cu
#include "kernel.cuh"

int InitDCMem(SimuationStruct *sim)
{
  SimParamGPU h_simparam;

  h_simparam.na = sim->det.na;
  h_simparam.nz = sim->det.nz;
  h_simparam.nr = sim->det.nr;

  cudaMemcpyToSymbol(d_simparam, &h_simparam, sizeof(SimParamGPU));
}  

数据结构(在头文件中):

//kernel.cuh

typedef struct __align__(16)
{
  int na;
  int nz;
  int nr;
} SimParamGPU;

__constant__ SimParamGPU d_simparam;

问题是这些值似乎没有被复制到 GPU 中的常量内存中。

我是否需要像cudaMemcpyToSymbol do not copy data 中所述在\\mem.cu 上重新声明__constant__
我应该在某处使用extern 吗?

没有错误,值始终设置为 0。

【问题讨论】:

  • 你确定你可以编译你的代码吗? cudaMemcpyToSymbol() 您使用的语法似乎不正确。看看here
  • 您展示的内容没有任何问题。我建立了一个测试here;没有问题。 SO 期望:“有关您编写的代码问题的问题必须在问题本身中描述具体问题 - 并包括有效的代码来重现它。请参阅 SSCCE.org 以获得指导。” 投票结束 - 缺少 SSCCE。组织代码。 This 可能很有趣,但根据您的描述,所需的一切都在同一个编译单元中。
  • 好吧,因为我的计算能力为 1.3,所以编译单元必须是 __constant__ 的一个。我正在寻求解决该限制的方法,并且......更重要的是......如果这可能是我看到寄存器上的值等于 0 而这些值在主机端正确设置的原因。
  • Example 可能的解决方案。在 Nsight 中如何配置 Generate Relocatable Device Code 选项?显然我不能,因为我的计算能力是 1.3
  • @mrei Nsight Eclipse 版在您选中 Build/Settings 项目属性页面上的“单独编译”时启用 Generate Relocatable Device Code。

标签: eclipse cuda memcpy nsight tesla


【解决方案1】:

你的内核在哪里?从编译器的角度来看,d_simparam 与您的主机代码在同一个“翻译单元”中 - 您在这里不需要任何“外部”声明。您可能在内核所在的源文件中需要一个。

这对我有用:

device.h - 带有设备符号的文件:

#include <stdio.h>

struct SimpleStruct {
    int a;
    float b;
};

__constant__ SimpleStruct variable = { 10, 0.3f };

__global__ void kernel() {
    printf("%d %f\n", variable.a, variable.b);
}

host.cu - 主机代码:

#include <stdio.h>
#include <stdlib.h>

#define CUDA_CHECK_RETURN(value) {                                      \
    cudaError_t _m_cudaStat = value;                                    \
    if (_m_cudaStat != cudaSuccess) {                                   \
        fprintf(stderr, "Error %s at line %d in file %s\n",             \
                cudaGetErrorString(_m_cudaStat), __LINE__, __FILE__);   \
    exit(1);                                                            \
} }

#include "device.h"

int main(void) {
    const SimpleStruct n = { 7, 0.5f };

    CUDA_CHECK_RETURN(cudaMemcpyToSymbol(variable, &n, sizeof(SimpleStruct)));

    kernel<<<1, 1>>>();

    CUDA_CHECK_RETURN(cudaThreadSynchronize()); // Wait for the GPU launched work to complete
    CUDA_CHECK_RETURN(cudaGetLastError());
    CUDA_CHECK_RETURN(cudaDeviceReset());

    return 0;
}

更新: 仅 SM 2.0 和更新的设备支持单独编译。不能对 SM 1.3 代码使用单独编译。

【讨论】:

  • 如果我的__constant__ 在包含在host.cu 文件中的头文件中?
  • 内核代码在哪里? #include 是一种文本操作 - 预处理器只需将整个标头放入源文件中。您需要在常量变量声明下方包含内核代码。
  • @mrei 在我的示例中,将 device.cu 重命名为 device.cuh 并将 host.cu 中的两个“externs”替换为单个 #include "device.cuh" - 我刚刚尝试过,它可以工作.
  • 内核调用在另一个完全不同的源文件中
  • 您必须将内核代码放入同一个源文件(直接或使用#include)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多