gpt4 book ai didi

__device__ 变量上的 cudaMemcpyFromSymbol

转载 作者:行者123 更新时间:2023-12-01 10:45:49 24 4
gpt4 key购买 nike

我正在尝试在 __device__ 变量上应用内核函数,根据规范,该变量驻留在“全局内存中”

#include <stdio.h>
#include "sys_data.h"
#include "my_helper.cuh"
#include "helper_cuda.h"
#include <cuda_runtime.h>


double X[10] = {1,-2,3,-4,5,-6,7,-8,9,-10};
double Y[10] = {0};
__device__ double DEV_X[10];


int main(void) {
checkCudaErrors(cudaMemcpyToSymbol(DEV_X, X,10*sizeof(double)));
vector_projection<double><<<1,10>>>(DEV_X, 10);
getLastCudaError("oops");
checkCudaErrors(cudaMemcpyFromSymbol(Y, DEV_X, 10*sizeof(double)));
return 0;
}

内核函数vector_projectionmy_helper.cuh中定义如下:

template<typename T> __global__ void vector_projection(T *dx, int n) {
int tid;
tid = threadIdx.x + blockIdx.x * blockDim.x;
if (tid < n) {
if (dx[tid] < 0)
dx[tid] = (T) 0;
}
}

如您所见,我使用 cudaMemcpyToSymbolcudaMemcpyFromSymbol 将数据传入和传出设备。但是,我收到以下错误:

CUDA error at ../src/vectorAdd.cu:19 code=4(cudaErrorLaunchFailure) 
"cudaMemcpyFromSymbol(Y, DEV_X, 10*sizeof(double))"

脚注:我当然可以避免使用 __device__ 变量并寻求一些东西 like this效果很好;我只想看看如何使用 __device__ 变量做同样的事情(如果可能的话)。

更新 cuda-memcheck 的输出可以在 http://pastebin.com/AW9vmjFs 找到.我收到的错误消息如下:

========= Invalid __global__ read of size 8
========= at 0x000000c8 in /home/ubuntu/Test0001/Debug/../src/my_helper.cuh:75:void vector_projection<double>(double*, int)
========= by thread (9,0,0) in block (0,0,0)
========= Address 0x000370e8 is out of bounds

最佳答案

问题的根源在于你是not allowed to take the address of a device variable in ordinary host code :

vector_projection<double><<<1,10>>>(DEV_X, 10);
^

虽然这似乎编译正确,但实际传递的地址是垃圾。

要获取主机代码中设备变量的地址,我们可以使用cudaGetSymbolAddress

这是一个为我正确编译和运行的工作示例:

$ cat t577.cu
#include <stdio.h>

double X[10] = {1,-2,3,-4,5,-6,7,-8,9,-10};
double Y[10] = {0};
__device__ double DEV_X[10];

template<typename T> __global__ void vector_projection(T *dx, int n) {
int tid;
tid = threadIdx.x + blockIdx.x * blockDim.x;
if (tid < n) {
if (dx[tid] < 0)
dx[tid] = (T) 0;
}
}



int main(void) {
cudaMemcpyToSymbol(DEV_X, X,10*sizeof(double));
double *my_dx;
cudaGetSymbolAddress((void **)&my_dx, DEV_X);
vector_projection<double><<<1,10>>>(my_dx, 10);
cudaMemcpyFromSymbol(Y, DEV_X, 10*sizeof(double));
for (int i = 0; i < 10; i++)
printf("%d: %f\n", i, Y[i]);
return 0;
}
$ nvcc -arch=sm_35 -o t577 t577.cu
$ cuda-memcheck ./t577
========= CUDA-MEMCHECK
0: 1.000000
1: 0.000000
2: 3.000000
3: 0.000000
4: 5.000000
5: 0.000000
6: 7.000000
7: 0.000000
8: 9.000000
9: 0.000000
========= ERROR SUMMARY: 0 errors
$

这不是解决此问题的唯一方法。在设备代码中获取设备变量的地址是合法的,因此您可以使用如下行修改内核:

T *dx = DEV_X;

并放弃将设备变量作为内核参数传递。正如评论中所建议的,您还可以修改代码以使用 Unified Memory .

关于错误检查,如果你偏离proper cuda error checking并且在你的偏差中不小心,结果可能会令人困惑。除了自身行为引起的错误之外,大多数 cuda API 调用还可以返回由某些先前的 CUDA 异步事件(通常是内核调用)导致的错误。

关于__device__ 变量上的 cudaMemcpyFromSymbol,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26075972/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com