Cuda 二维倾斜阵列的立方和归约
我正在尝试使用float/double类型的CUB和2D数组执行求和缩减。 虽然它适用于行+列的某些组合,但对于相对较大的数组,我在上次传输期间遇到了非法内存访问错误。 下面是一个简单的例子:Cuda 二维倾斜阵列的立方和归约,cuda,cub,Cuda,Cub,我正在尝试使用float/double类型的CUB和2D数组执行求和缩减。 虽然它适用于行+列的某些组合,但对于相对较大的数组,我在上次传输期间遇到了非法内存访问错误。 下面是一个简单的例子: #include <stdio.h> #include <stdlib.h> #include <cub/device/device_reduce.cuh> #include "cuda_runtime.h" #ifdef DP #define
#include <stdio.h>
#include <stdlib.h>
#include <cub/device/device_reduce.cuh>
#include "cuda_runtime.h"
#ifdef DP
#define real double
#else
#define real float
#endif
void generatedata(const int num, real* vec, real start, real finish) {
real rrange = finish - start;
for (auto i = 0; i < num; ++i)
vec[i] = rand() / float(RAND_MAX) * rrange + start;
}
real reduce_to_sum(const int num, const real* vec) {
real total = real(0.0);
for (auto i = 0; i < num; ++i)
total += vec[i];
return total;
}
int main() {
int rows = 2001;
int cols = 3145;
size_t msize = rows * cols;
real* data = (real*)malloc(msize * sizeof(real));
if (!data)
return -999;
generatedata(msize, data, 0., 50.);
real ref_sum = reduce_to_sum(msize, data);
real* d_data_in = nullptr;
real* d_data_out = nullptr;
size_t pitch_in, pitch_out;
cudaError_t err = cudaMallocPitch(&d_data_in, &pitch_in, cols * sizeof(real), rows);
if (err != cudaSuccess) {
printf("data_in :: %s \n", cudaGetErrorString(err));
return -999;
}
err = cudaMallocPitch(&d_data_out, &pitch_out, cols * sizeof(real), rows);
if (err != cudaSuccess) {
printf("data_out :: %s \n", cudaGetErrorString(err));
return -999;
}
err = cudaMemset(d_data_in, 0, rows * pitch_in);
if (err != cudaSuccess) {
printf("set data_in :: %s \n", cudaGetErrorString(err));
return -999;
}
err = cudaMemcpy2D(d_data_in, pitch_in, data, cols * sizeof(real), cols * sizeof(real), rows, cudaMemcpyHostToDevice);
if (err != cudaSuccess) {
printf("copy data :: %s \n", cudaGetErrorString(err));
return -999;
}
void* d_temp = nullptr;
size_t temp_bytes = 0;
cub::DeviceReduce::Sum(d_temp, temp_bytes, d_data_in, d_data_out, rows * pitch_out);
err = cudaMalloc(&d_temp, temp_bytes);
if (err != cudaSuccess) {
printf("temp :: %s \n", cudaGetErrorString(err));
return -999;
}
err = cudaMemset(d_data_out, 0, rows * pitch_out);
if (err != cudaSuccess) {
printf("set temp :: %s \n", cudaGetErrorString(err));
return -999;
}
// Run sum-reduction
cub::DeviceReduce::Sum(d_temp, temp_bytes, d_data_in, d_data_out, rows * pitch_out);
err = cudaGetLastError();
if (err != cudaSuccess) {
printf("reduction :: %s \n", cudaGetErrorString(err));
return -999;
}
real gpu_sum = real(0.0);
err = cudaMemcpy(&gpu_sum, d_data_out, sizeof(real), cudaMemcpyDeviceToHost);
if (err != cudaSuccess) {
printf("copy final :: %s \n", cudaGetErrorString(err));
return -999;
}
printf("Difference in sum (h)%f - (d)%f = %f \n", ref_sum, gpu_sum, ref_sum - gpu_sum);
if (data) free(data);
if (d_data_in) cudaFree(d_data_in);
if (d_data_out) cudaFree(d_data_out);
if (d_temp) cudaFree(d_temp);
cudaDeviceReset();
return 0;
}
#包括
#包括
#包括
#包括“cuda_runtime.h”
#ifdef-DP
#定义实双精度
#否则
#定义实浮点
#恩迪夫
void generatedata(常量int num、实*vec、实起点、实终点){
实际安排=完成-开始;
用于(自动i=0;i
错误在“复制最终版本::”处抛出。我有点困惑,为什么某些行x列可以工作,而其他行x列不能工作。我确实注意到是更大的值导致了它,但我无法理解。
任何建议都将不胜感激。cub::DeviceReduce::Sum的第五个参数应该是输入元素的数量。但是,
rows*pitch_out
是输出缓冲区的大小(以字节为单位)
假设以%sizeof(real)==0为基音,则以下调用可能有效
cub::DeviceReduce::Sum(d_temp、temp_字节、d_data_in、d_data_out、rows*(pitch_in/sizeof(real))代码>
还要注意,cub::DeviceReduce::Sum可能会在缩减完成之前返回。在这种情况下,如果在执行过程中发生任何错误,cudaMemcpy将报告此错误。cub::DeviceReduce::Sum的第5个参数应该是输入元素的数量。但是,rows*pitch_out
是输出缓冲区的大小(以字节为单位)
假设以%sizeof(real)==0为基音,则以下调用可能有效
cub::DeviceReduce::Sum(d_temp、temp_字节、d_data_in、d_data_out、rows*(pitch_in/sizeof(real))代码>
还要注意,cub::DeviceReduce::Sum可能会在缩减完成之前返回。在这种情况下,如果在执行过程中发生任何错误,cudaMemcpy将报告此错误