私は既存の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'...
を参照してください?両方の実装が完全にIEEE754準拠( 'sqrt'関数を含む - 通常はそうではない)でない限り、100%同一の出力を期待することはできません。この精度のレベルがあなたに受け入れられない場合は、両方のプラットフォームで 'double'sを使用するように切り替えることができます。 (64ビットの二重サポートを有効にすることを忘れないでください) – pmdj
@pmdj CUDAの出力が正しいとは思いません。 OpenCL出力はCPU出力からも異なります。 OpenCLを使用してCPU出力またはCUDA出力を再現したい。 – Avis
@ pmdjの精度差が-5〜-6です。しかし、^ -3は出力に非常に大きな影響を与えます。 – Avis