首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >cudaMemcpyToSymbol对cudaMemcpy

cudaMemcpyToSymbol对cudaMemcpy
EN

Stack Overflow用户
提问于 2013-03-13 16:44:47
回答 1查看 4.4K关注 0票数 0

我想弄清楚为什么cudaMemcpyToSymbol不为我工作。(但cudaMemcpy有。)

代码语言:javascript
复制
// symbols:
__constant__ float flt[480];   // 1920 bytes
__constant__ int   ints[160];  // 640 bytes

// func code follows:
float* pFlts;
cudaMalloc((void**)&pFlts, 1920+640);  // chunk of gpu mem  (floats & ints)

// This does NOT work properly:
cudaMemcpyToSymbol(flt,pFlts,1920,0,cudaMemcpyDeviceToDevice);  // first copy
cudaMemcpyToSymbol(ints,pFlts,640,1920,cudaMemcpyDeviceToDevice);  // second copy

第二个副本正在破坏第一个副本(flt)的内容,而第二个副本则不会发生。(如果删除第二份副本,则第一份副本工作正常。)

结果:

代码语言:javascript
复制
GpuDumpFloatMemory<<<1,1>>>(0x500500000, 13, 320)  TotThrds=1   ** Source of 1st copy
  0x500500500: float[320]= 1.000
  0x500500504: float[321]= 0.866
  0x500500508: float[322]= 0.500
  0x50050050c: float[323]= -0.000
  0x500500510: float[324]= -0.500
  0x500500514: float[325]= -0.866
  0x500500518: float[326]= -1.000
  0x50050051c: float[327]= -0.866
  0x500500520: float[328]= -0.500
  0x500500524: float[329]= 0.000
  0x500500528: float[330]= 0.500
  0x50050052c: float[331]= 0.866
  0x500500530: float[332]= 1.000
  GpuDumpFloatMemory<<<1,1>>>(0x500100a98, 13, 320)  TotThrds=1     ** Dest of 1st copy
  0x500100f98: float[320]= 0.000
  0x500100f9c: float[321]= 0.500
  0x500100fa0: float[322]= 0.866
  0x500100fa4: float[323]= 1.000
  0x500100fa8: float[324]= 0.866
  0x500100fac: float[325]= 0.500
  0x500100fb0: float[326]= -0.000
  0x500100fb4: float[327]= -0.500
  0x500100fb8: float[328]= -0.866
  0x500100fbc: float[329]= -1.000
  0x500100fc0: float[330]= -0.866
  0x500100fc4: float[331]= -0.500
  0x500100fc8: float[332]= 0.000
  GpuDumpIntMemory<<<1,1>>>(0x500500780, 13, 0)  TotThrds=1      ** Source of 2nd copy
  0x500500780: int[0]= 1
  0x500500784: int[1]= 1
  0x500500788: int[2]= 1
  0x50050078c: int[3]= 1
  0x500500790: int[4]= 1
  0x500500794: int[5]= 1
  0x500500798: int[6]= 1
  0x50050079c: int[7]= 1
  0x5005007a0: int[8]= 1
  0x5005007a4: int[9]= 1
  0x5005007a8: int[10]= 1
  0x5005007ac: int[11]= 1
  0x5005007b0: int[12]= 0
  GpuDumpIntMemory<<<1,1>>>(0x500100818, 13, 0)  TotThrds=1      ** Dest of 2nd copy
  0x500100818: int[0]= 0
  0x50010081c: int[1]= 0
  0x500100820: int[2]= 0
  0x500100824: int[3]= 0
  0x500100828: int[4]= 0
  0x50010082c: int[5]= 0
  0x500100830: int[6]= 0
  0x500100834: int[7]= 0
  0x500100838: int[8]= 0
  0x50010083c: int[9]= 0
  0x500100840: int[10]= 0
  0x500100844: int[11]= 0
  0x500100848: int[12]= 0

下列各项工作正常:

代码语言:javascript
复制
cudaMemcpyToSymbol(flt,pFlts,1920,0,cudaMemcpyDeviceToDevice);  // first copy
int* pTemp;
cudaGetSymbolAddress((void**) &pTemp, ints);
cudaMemcpy(ints,pFlts+480,640,cudaMemcpyDeviceToDevice);  // second copy

结果:

代码语言:javascript
复制
  GpuDumpFloatMemory<<<1,1>>>(0x500500000, 13, 320)  TotThrds=1   ** Source of first copy
  0x500500500: float[320]= 1.000
  0x500500504: float[321]= 0.866
  0x500500508: float[322]= 0.500
  0x50050050c: float[323]= -0.000
  0x500500510: float[324]= -0.500
  0x500500514: float[325]= -0.866
  0x500500518: float[326]= -1.000
  0x50050051c: float[327]= -0.866
  0x500500520: float[328]= -0.500
  0x500500524: float[329]= 0.000
  0x500500528: float[330]= 0.500
  0x50050052c: float[331]= 0.866
  0x500500530: float[332]= 1.000
  GpuDumpFloatMemory<<<1,1>>>(0x500100a98, 13, 320)  TotThrds=1    ** Dest of first copy
  0x500100f98: float[320]= 1.000
  0x500100f9c: float[321]= 0.866
  0x500100fa0: float[322]= 0.500
  0x500100fa4: float[323]= -0.000
  0x500100fa8: float[324]= -0.500
  0x500100fac: float[325]= -0.866
  0x500100fb0: float[326]= -1.000
  0x500100fb4: float[327]= -0.866
  0x500100fb8: float[328]= -0.500
  0x500100fbc: float[329]= 0.000
  0x500100fc0: float[330]= 0.500
  0x500100fc4: float[331]= 0.866
  0x500100fc8: float[332]= 1.000
  GpuDumpIntMemory<<<1,1>>>(0x500500780, 13, 0)  TotThrds=1    ** Source of 2nd copy
  0x500500780: int[0]= 1
  0x500500784: int[1]= 1
  0x500500788: int[2]= 1
  0x50050078c: int[3]= 1
  0x500500790: int[4]= 1
  0x500500794: int[5]= 1
  0x500500798: int[6]= 1
  0x50050079c: int[7]= 1
  0x5005007a0: int[8]= 1
  0x5005007a4: int[9]= 1
  0x5005007a8: int[10]= 1
  0x5005007ac: int[11]= 1
  0x5005007b0: int[12]= 0
  GpuDumpIntMemory<<<1,1>>>(0x500100818, 13, 0)  TotThrds=1    ** Destination of 2nd copy
  0x500100818: int[0]= 1
  0x50010081c: int[1]= 1
  0x500100820: int[2]= 1
  0x500100824: int[3]= 1
  0x500100828: int[4]= 1
  0x50010082c: int[5]= 1
  0x500100830: int[6]= 1
  0x500100834: int[7]= 1
  0x500100838: int[8]= 1
  0x50010083c: int[9]= 1
  0x500100840: int[10]= 1
  0x500100844: int[11]= 1
  0x500100848: int[12]= 0

当我看到坏的情况时,似乎符号表发生了什么事情。正如所述,第一个复制目的地的数据非常熟悉。不是被改写了,只是移动了一下。就像指针错了一样。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-13 17:24:38

第二份在我看来是坏的。您已经定义了这个数组:

代码语言:javascript
复制
__constant__ int   ints[160];  // 640 bytes

正如正确指出的,它有640字节长。

你的第二份是这样的:

代码语言:javascript
复制
cudaMemcpyToSymbol(ints,pFlts,640,1920,cudaMemcpyDeviceToDevice);  // second copy

它表示,“将总共640个字节从pFlts数组复制到ints数组,从数组开始时,ints数组中的存储位置从190个字节开始。”

这不管用。ints数组只有640个字节长。你不能选择一个1920年字节的位置作为你的目的地。

来自cudaMemcpyToSymbol的文档:

偏移量-从符号开始偏移(以字节为单位)

在这种情况下,符号是ints

也许你想要的是:

代码语言:javascript
复制
cudaMemcpyToSymbol(ints,pFlts+480,640,0,cudaMemcpyDeviceToDevice);  // second copy

编辑:在回答有关错误检查的评论中的问题时,我构建了这个简单的测试程序:

代码语言:javascript
复制
#include <stdio.h>

#define cudaCheckErrors(msg) \
    do { \
        cudaError_t __err = cudaGetLastError(); \
        if (__err != cudaSuccess) { \
            fprintf(stderr, "Fatal error: %s (%s at %s:%d)\n", \
                msg, cudaGetErrorString(__err), \
                __FILE__, __LINE__); \
            fprintf(stderr, "*** FAILED - ABORTING\n"); \
            exit(1); \
        } \
    } while (0)

__constant__ int ints[160];

int main(){

  int *d_ints;
  cudaError_t mystatus;

  cudaMalloc((void **)&d_ints, sizeof(int)*160);
  cudaCheckErrors("cudamalloc fail");
  mystatus = cudaMemcpyToSymbol(ints, d_ints, 160*sizeof(int), 1920, cudaMemcpyDeviceToDevice);
  if (mystatus != cudaSuccess) printf("returned value was not cudaSuccess\n");
  cudaCheckErrors("cudamemcpytosymbol fail");

  printf("OK!\n");
  return 0;
}

当我编译和运行它时,我得到以下输出:

代码语言:javascript
复制
returned value was not cudaSuccess
Fatal error: cudamemcpytosymbol fail (invalid argument at t94.cu:26)
*** FAILED - ABORTING

这表示来自cudaMemcpyToSymbol函数调用的错误返回值和cudaGetLastError()方法在这种情况下都返回错误。如果在这个测试用例中将1920参数更改为零,错误就会消失。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15391394

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档