2012-10-07 5 views
6

非決定的と思われる私は、コードをコンパイルして実行すると、私は期待どおりに動作しますが、(pycuda経由)、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"); 
     } 
    } 
} 

を以下のスニペットで

をCUDAとの奇妙な問題を持っています。 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(分))

私は理由が分かりません。

私はのGeForce 570

おかげでpycudaに2012.2(Windows 7の64ビット版)をCUDA 4.2を実行してきました。

+0

申し訳ありませんが、64 LinuxのホストとGTX 670でCUDA 4.2を使用してこれを再現することはできません。投稿したときにカーネルを使用して実行するたびに、単精度と倍精度の両方のバージョンが渡されます。 – talonmies

+0

私は欠陥のあるハードウェアを持っていると思うが、なぜ4.2GPU SDKの他のすべてのcudaプログラムがうまく動作するのか分からない。私はLinuxで同じハードウェアでこれを実行しようとします - そして、私はWindowsで異なるハードウェアを試してみるでしょう。 。 。 – user1726633

+0

pycudaは分かりませんが、C/C++では '__global__'や' __device__'コードの中で 'printf'関数を使うことはできません。それはpycudaで可能ですか? – szamil

答えて

1

これは、おそらくコンパイラの最適化によるものです。長さがOUTPUT_SIZEのメモリブロックをidのループ定数値に設定しています。私の経験では、コンパイラは、ループ内で何かが起こっている場合を除いて、memcpyまたはwhathaveyou に最適化します。つまり、print文です。さらに、そのメモリブロックを利用しない場合、コンパイラはループ全体を最適化するかもしれません。最適化レベルを試してみて、結果が異なるかどうかを確認してください。

関連する問題