使用大数组时内核出错

时间:2016-02-01 16:35:39

标签: arrays cuda

使用简单的函数来设置CUDA数组时,我得到invalid argument大数组(大约> pow(2,25))。

我正在使用特斯拉k40。我应该有足够的内存(到目前为止)分配数组,并且还有足够的容量来抛出我的块数,但下面的代码退出时出现错误:

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

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

#define MAXTHREADS 1024
//http://stackoverflow.com/a/16283216/1485872
#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)

__global__ void mymemset(float* image, const float val, size_t N)
{
    //http://stackoverflow.com/a/35133396/1485872
    size_t tid = threadIdx.x + blockIdx.x * blockDim.x;
    while (tid < N) {
        image[tid] = val;
        tid += gridDim.x * blockDim.x;
    }
}


int main()
{

    size_t total_pixels = pow(2, 26) ;
    float* d_image;
    cudaMalloc(&d_image, total_pixels*sizeof(float));
    cudaCheckErrors("Malloc");

    dim3 bsz = dim3(MAXTHREADS);
    dim3 gsz = dim3(total_pixels / bsz.x + ((total_pixels % bsz.x > 0) ? 1 : 0));
    mymemset << <gsz, bsz >> >(d_image, 1.0f, total_pixels);
    cudaCheckErrors("mymemset"); //<- error!
    cudaDeviceReset();

    }

pow(2,25)中的代码可以正常工作(以及更多)total_pixelspow(2,26)失败。

巧合的是,这是块大小bsz65536的点,这似乎是某些GPU的上限,但在特斯拉k40中,它应该是2147483647 x尺寸,65536y z(我不使用)。有关此错误起源的任何见解?

VS2013的编译器标志:属性 - > CUDA C / C ++ /命令行

# Driver API (NVCC Compilation Type is .cubin, .gpu, or .ptx)
set CUDAFE_FLAGS=--sdk_dir "C:\Program Files (x86)\Windows Kits\8.1\"
"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\bin\nvcc.exe" --use-local-env --cl-version 2013 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin"     -G   --keep-dir Debug -maxrregcount=0  --machine 32 --compile -cudart static  -o Debug\%(Filename)%(Extension).obj "%(FullPath)"

# Runtime API (NVCC Compilation Type is hybrid object or .c file)
set CUDAFE_FLAGS=--sdk_dir "C:\Program Files (x86)\Windows Kits\8.1\"
"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\bin\nvcc.exe" --use-local-env --cl-version 2013 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin"     -G   --keep-dir Debug -maxrregcount=0  --machine 32 --compile -cudart static  -g    -Xcompiler "/EHsc  /nologo  /Zi   " -o Debug\%(Filename)%(Extension).obj "%(FullPath)"

1 个答案:

答案 0 :(得分:2)

您正在编译默认架构(sm_20),其网格的每个维度的块大小限制为65535。您必须为sm_35构建才能在一维网格中启动2147483647块。

你还应该注意,你正在使用的内核(我写的)可以使用比(n / blocksize)少得多的块来运行,并且仍能正常工作,并且more efficient这样做。