2017-05-26 4 views
1

OpenCLにいくつかの並列BLASルーチンを実装しました。カーネルが正しいかどうかを調べるために、同じルーチンを素朴な方法で実装しました。カーネルを実行した後、カーネルの結果を素朴な実装の結果と比較します。並列化されたBLASルーチンの結果の確認

floatの値を==と比較することはできません。したがって、私は2つの絶対差を計算し、それが限界を超えているかどうかを確認します。私は既にfloatsを比較するいくつかの他の方法を記述するthis articleを読みました。しかし、私の問題は、floatsを比較するために使用する制限がわかりません。私の場合、限界はBLASルーチンと入力サイズに大きく依存しているようです。

たとえば、float値のベクトルの絶対値の合計を計算するasumを実装しました。サイズ16777216の入力ベクトルの場合、素朴な実装と私の並列化された実装の違いは96です! 1 048 576の入力サイズの場合、その差はわずか0.5です。私は小さな入力サイズで手作業で結果をチェックしたので、私のカーネルは正しいと確信しています。私は大きな入力ベクトルのために差が蓄積していると推測しています。

私の質問は、floatの不正確さから生じる可能性のある最大の違いを計算する方法はありますか?カーネルコードのエラーのために違いがあるのか​​どうかを知る方法はありますか?

+0

期待される偏差は入力の大きさに依存しますので、使用できる単一の定数の制限はありません – harold

+0

正確な入力サイズを知っています。 –

+0

厳しいルールはありませんか? –

答えて

2

ここで使用できるインターバル数学というテクニックがあります。代わりにあなたが許容できると考えるいくつかの固定されたエラーを持っていることの

は、あなたが与えられた浮動小数点演算が「実際に」を参照することができ最もと少なくとも値を追跡します。

Wikipedia has an article on it

ライブラリーが見つからない場合は、インターバルフロートタイプを作成します。それは、2つの浮動小数点数を含み、間隔が表すことができる最高値と最低値を表します。

丸めの効果を含めると、+*/とが上書きされます。それは仕事を書くだろう。 3.0の値の範囲が1.02.0秒の誤差を考慮するのに十分な大きさでありとして

ですから、{1.0,1.0}{2.0,2.0}を追加した場合、その答えは、{3.0,3.0}だろう。

{3.0, 3.0}のエラーが{1.0, 1.0}で示されるエラーよりも大きいため、答えは{0.9999999999997, 1.00000000003}などとなります。

同じことが乗算と除算に当てはまります。

分裂がある場合は、これらの間隔が「inf/nanを含むすべての可能な数」に達するのは驚くほど簡単です。そして、前述したように、減算は重大な問題につながります。キャンセルする言葉が大量にある場合は、予想よりもはるかに大きなエラーバーで簡単に終わることがあります。

最後に、あなたのOpenCLソリューションがその期間内に値をもたらすならば、あなたは「よく、それは間違っていない」と言うことができます。

+0

ありがとうございます。 2.0の減算が '{0.9999999999997、1.00000000003}'になる理由を詳しく説明できますか?区間数学では、{3.0,3.0}の両方の要素から2.0を引くと考えました。なぜ2つの異なる値になるのでしょうか? –

+0

@Richard値の範囲「1.0」は、丸めのため、1.0で浮動小数点エラー「1 +/-浮動小数点エラー」を表します。 '2 +/- error at 2.0'と' 3 +/- error at 3.0'を引くと、 '1 +/-(2.0のエラー+ 3.0のエラー)'が得られます。浮動小数点誤差がより大きい値になると、これは「1.0の誤差」よりも大きい。これを反映するために、浮動小数点値の間隔は、「最大値1.0が表すことができ、最小値1.0を表すことができる」ではなく、「最大値1.0000000003が表すことができ、最小値0.999999997は表すことができる」(これらの値は正確ではない) 。 – Yakk

関連する問題