2017-07-21 17 views
0

私は既存のCUDA関数を移植することでOpenCLを学んでいます。以下は私のCUDAとOpenCLカーネルです。同じ入力パラメータが両方の関数に渡されると、出力は^ -3〜^ -4のオーダで異なります。これらの関数を繰り返し呼び出すと、差の次数が大幅に増加します(これは期待される出力には非常に悪い)。 OpenCL移植に何か問題はありますか?CUDA対OpenCL:浮動小数点精度の変更

注:

__global__ void normalize_kernel(int N, float *x, float *mean, float *variance, int batch, int filters, int spatial) 
{ 
    int index = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; 
    if (index >= N) return; 
    int f = (index/spatial)%filters; 

    x[index] = (x[index] - mean[f])/(sqrt(variance[f] + .00001f)); 
} 

のOpenCLカーネル:

__kernel void normalize_kernel(int N, __global float *x, __global float *mean, __global float *variance, int filters, int spatial) 
{ 
    int index = get_group_id(1) * get_global_size(0) + get_global_id(0); 
    if (index >= N) return; 
    int f = (index/spatial)%filters; 

    x[index] = (x[index] - mean[f])/(sqrt(variance[f] + .00001f)); 
} 

出力:CUDA

CUDAカーネルのOpenCLカーネルをコンパイルしながら、私はすでに "-cl-OPT-無効" 試してみました:OpenCL

{'1.293604': '1.293387', 
'0.727771': '0.727677', 
'0.868133': '0.867531', 
'2.195427': '2.195059'... 
+0

を参照してください?両方の実装が完全にIEEE754準拠( 'sqrt'関数を含む - 通常はそうではない)でない限り、100%同一の出力を期待することはできません。この精度のレベルがあなたに受け入れられない場合は、両方のプラットフォームで 'double'sを使用するように切り替えることができます。 (64ビットの二重サポートを有効にすることを忘れないでください) – pmdj

+0

@pmdj CUDAの出力が正しいとは思いません。 OpenCL出力はCPU出力からも異なります。 OpenCLを使用してCPU出力またはCUDA出力を再現したい。 – Avis

+0

@ pmdjの精度差が-5〜-6です。しかし、^ -3は出力に非常に大きな影響を与えます。 – Avis

答えて

0

コンパイルオプション(OpenCL 1.2以上)-cl-fp32-correctly-rounded-divide-sqrtをチェックしてください。いくつかのハードウェアでは、これはあなたのパフォーマンスを少し遅くしますが、それほど大きな問題ではないかもしれません。

あなたはCUDA出力がOpenCLの者よりも「より正確」であると思わせる何か https://www.khronos.org/registry/OpenCL/sdk/1.2/docs/man/xhtml/clCompileProgram.html

+0

ありがとう、それをチェックアウトします。 – Avis

+0

OpenCL 1.1でこれに相当するものはありますか? – Avis

関連する問題