2014-09-01 4 views
-1

Я новичок в программировании CUDA, и я пытаюсь загрузить ядро ​​CUDA в C# с помощью управляемого CUDA, но я все еще получаю сообщение об ошибке во время вызова метода ядра.managedCUDA: Запуск собственного ядра - Ошибка: InvalidValue

ErrorInvalidValue: This indicates that one or more of the parameters passed to the API call is not within an acceptable range of values. 

Я получаю эту ошибку, даже когда я называю kernel.Run() или kernel.RunAsync((new CudaStream()).Stream) - когда мое ядро ​​не имеет какого-либо параметра.

Кто-нибудь знает, что не так? Или может кто-нибудь указать мне в правильном направлении, пожалуйста ... Thats много для любой помощи!

Мой kernel.cu код:

#include <stdio.h> 
#include <cuda.h> 
#include <cuda_runtime.h> 
#include "device_launch_parameters.h" 

extern "C" { 
    __global__ void func() 
    { 
     const int numThreads = blockDim.x * gridDim.x; 
     const int threadID = blockIdx.x * blockDim.x + threadIdx.x; 
     //do nothing 
    } 
} 

kernel.ptx:

.version 1.4 
    .target sm_11, map_f64_to_f32 
    // compiled with C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v6.0\bin/../open64/lib//be.exe 
    // nvopencc 4.1 built on 2014-03-14 
    ...some more comments... 

    .file 1 "<filename>.gpu" 
    ...next 33 .file(s) 

    .entry func 
    { 
    .loc 15 52 0 
$LDWbegin_func: 
    .loc 15 57 0 
    exit; 
$LDWend_func: 
    } // func 

и C# программы:

 string resName; 
     if (IntPtr.Size == 8) 
      resName = "kernel_64.ptx"; 
     else 
      resName = "kernel.ptx"; 

     string resNamespace = "signalViewer.CUDA"; 
     string resource = resNamespace + "." + resName; 
     Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource); 
     if (stream == null) throw new ArgumentException("Kernel not found in resources."); 

     CudaKernel func= ctx.LoadKernelPTX(stream, "func"); 

     dim3 threads = new dim3(512, 1); 
     dim3 blocks = new dim3(N/(int)threads.x, 1); 

     func.BlockDimensions = threads; 
     func.GridDimensions = blocks; 
     func.RunAsync((new CudaStream()).Stream); 
     //func.Run(); 
+1

Что такое значение N? – Jez

+0

Большое спасибо @Jez! N было ниже (64), чем количество блоков (512), поэтому в финале было нулевое число блоков (64/512), я этого не заметил. – JiangHongTiao

ответ

1

Благодаря @Jez - я было число блоков, равное нулю

dim3 threads = new dim3(512, 1); 
dim3 blocks = new dim3(N/(int)threads.x, 1); 

N был 64

Лучшее решение:

int maxThreads = Math.Min(ctx.GetDeviceInfo().MaxThreadsPerBlock, N); 
    dim3 threads = new dim3(maxThreads, 1); 
    dim3 blocks = new dim3((N + maxThreads - 1)/maxThreads, 1); 
+1

Обычно количество блоков вычисляется потолком с делением с плавающей запятой или более удобно в целочисленной арифметике: blocks = ((N + maxThreads - 1)/maxThreads). Это число всегда будет> = 1. Затем вам также нужно проверить внутри ядра, если текущий threadID больше N! – kunzmi

+0

Спасибо @kunzmi, редактируя сообщение своим предложением и моим кодом тоже: -} – JiangHongTiao

Смежные вопросы