6

私はcudaに奇妙な問題を抱えています。

以下のスニペットでは、

#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 を使用すると、エラーは 0 になります。それがないと、ランダムなエラーが出力されます (私のマシンでは、約 2452 (最大の場合)、および -2583 (最小の場合))。

理由がわかりません。

Geforce 570 を使用して pycuda 2012.2 (Windows 7 64 ビット) で cuda 4.2 を実行しています。

ありがとう。

4

1 に答える 1

1

これは、コンパイラの最適化が原因である可能性が最も高いです。長さ OUTPUT_SIZE のメモリ ブロックを id の loop-constant 値に設定しています。私の経験では、コンパイラはそれを memcpy または whathaveyou に最適化しますが、ループで何か他のことが起こっていない限り、つまり print ステートメントです。さらに、そのメモリ ブロックを使用しない場合、コンパイラはループ全体を最適化する可能性があります。最適化レベルをいじってみて、結果が異なるかどうかを確認してください。

于 2013-06-25T18:24:16.877 に答える