2012-10-07 61 views
6

我有一個奇怪的問題,CUDA,pycuda似乎不確定性

在下面的代碼片段,

#include <stdio.h> 

#define OUTPUT_SIZE   26 

typedef $PRECISION REAL; 

extern "C"  
{ 
    __global__ void test_coeff (REAL* results) 
    { 
     int id  = blockDim.x * blockIdx.x + threadIdx.x; 

     int out_index = OUTPUT_SIZE * id; 
     for (int i=0; i<OUTPUT_SIZE; i++) 
     {    
      results[out_index+i]=id; 
      printf("q"); 
     } 
    } 
} 

當我編譯並運行代碼(通過pycuda),它按預期工作。當我刪除printf時,結果很奇怪 - 大部分數組都是正確填充的,但其中一些看起來完全是隨機的。

這裏是完整的Python代碼:

import numpy as np 
import string 

#pycuda stuff 
import pycuda.driver as drv 
import pycuda.autoinit 

from pycuda.compiler import SourceModule 

class MC: 

    cudacodetemplate = """ 
    #include <stdio.h> 

    #define OUTPUT_SIZE   26 

    typedef $PRECISION REAL; 

    extern "C"  
    { 
     __global__ void test_coeff (REAL* results) 
     { 
      int id  = blockDim.x * blockIdx.x + threadIdx.x; 

      int out_index = OUTPUT_SIZE * id; 
      for (int i=0; i<OUTPUT_SIZE; i++) 
      {    
       results[out_index+i]=id; 
       //printf("q"); 
      } 
     } 
    } 
    """ 

    def __init__(self, size, prec = np.float32): 
     #800 meg should be enough . . . 
     drv.limit.MALLOC_HEAP_SIZE = 1024*1024*800 

     self.size  = size 
     self.prec  = prec 
     template  = string.Template(MC.cudacodetemplate) 
     self.cudacode = template.substitute(PRECISION = 'float' if prec==np.float32 else 'double') 

     #self.module  = pycuda.compiler.SourceModule(self.cudacode, no_extern_c=True, options=['--ptxas-options=-v']) 
     self.module  = SourceModule(self.cudacode, no_extern_c=True) 

    def test(self, out_size): 
     #try to precalc the co-efficients for just the elements of the vector that changes 
     test = np.zeros((128, out_size*(2**self.size)), dtype=self.prec) 
     test2 = np.zeros((128, out_size*(2**self.size)), dtype=self.prec) 

     test_coeff = self.module.get_function ('test_coeff') 
     test_coeff(drv.Out(test), block=(2**self.size,1,1), grid=(128, 1)) 
     test_coeff(drv.Out(test2), block=(2**self.size,1,1), grid=(128, 1)) 
     error = (test-test2) 
     return error 

if __name__ == '__main__': 
    p1 = MC (5, np.float64) 
    err = p1.test(26) 
    print err.max() 
    print err.min() 

基本上,在內核中的printf,則err爲0 - 沒有它,它打印一些隨機誤差(我周圍2452的機器上(爲最大),和-2583(最小))

我不知道爲什麼。

我上pycuda用的GeForce 570

由於運行CUDA 4.2 2012.2(64位Windows 7)。

+0

對不起,但我無法在64位Linux主機和GTX 670上使用CUDA 4.2重現此操作。單次和雙精度版本每次在您發佈內核時都使用它們運行它們。 – talonmies

+0

我認爲我的硬件有問題 - 儘管我不確定爲什麼4.2 GPU SDK中的所有其他cuda程序都能正常工作。我會嘗試在linux中使用相同的硬件來運行這個 - 然後我會在Windows中嘗試不同的硬件並看看。 。 。 – user1726633

+0

我不知道pycuda,但在C/C++中,你不能在'__global__'或'__device__'代碼中使用'printf'函數。 pycuda可能嗎? – szamil

回答

1

這很可能是由於編譯器優化。您正在將一段內存OUTPUT_SIZE長度設置爲id的循環常量值。根據我的經驗,編譯器將優化到memcpy或whathaveyou 除非循環中還有其他事情正在進行 - 即您的打印語句。此外,如果你不使用那塊內存,編譯器可能會優化整個循環。嘗試擺弄你的優化級別,看看你是否有不同的結果。