- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在 __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_projection
在my_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;
}
}
如您所见,我使用 cudaMemcpyToSymbol
和 cudaMemcpyFromSymbol
将数据传入和传出设备。但是,我收到以下错误:
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/
我试图找出为什么 cudaMemcpyFromSymbol() 存在。似乎“symbol” func 可以做的所有事情,nonSymbol cmd 也可以做。 symbol 函数似乎可以轻松移动数组或
我正在尝试在 __device__ 变量上应用内核函数,根据规范,该变量驻留在“全局内存中” #include #include "sys_data.h" #include "my_helper.c
下面,我包含了一个使用 cudaMemcpyFromSymbol() 的自包含示例。从内核中检索结果。该示例将符号参数(调用中的第二个参数)作为常规变量传递。但是,据我了解 CUDA 文档,将参数作为
我想计算 CUDA 中数组所有元素的总和。我想出了这段代码。它编译没有任何错误。但结果始终为零。我从 cudaMemcpyFromSymbol 获得了无效的设备符号。我无法使用 Thrust 或 Cu
我对 CUDA 有点陌生,所以如果这是一个愚蠢的问题,请原谅我。我一直在阅读/观看很多教程,但它们都很困惑,但我认为我已经掌握了基本概念。无论如何,我正在尝试执行以下操作:我想在设备上初始化几个常量变
我是一名优秀的程序员,十分优秀!