私は OpenCL をいじり始めたばかりで、かなり効率的な方法でプログラムを構築する方法に行き詰まっています (主に、GPU との間、または作業が行われている場所での大量のデータ転送を回避します)。
私がやろうとしていることは、次のとおりです。
v = r*i + b*j + g*k
..とv
のさまざまな値を知っていますがr
、g
とは不明です。力ずくで/ /の妥当な値を計算したいb
i
j
k
i
j
k
言い換えれば、私は「生の」RGB ピクセル値の束を持っており、これらの色の彩度を下げたバージョンを持っています。彩度の低い値を計算するために使用される重み付け (i/j/k) がわかりません。
私の最初の計画は次のとおりでした。
データを CL バッファーにロードします (したがって、入力 r/g/b 値と出力)
3 つの可能なマトリックス値と、さまざまなピクセル データ バッファーを取るカーネルがあります。
次に を実行
v = r*i + b*j + g*k
し、 の値を既知の値から減算し、v
これを「スコア」バッファに格納します。別のカーネルがその値の RMS エラーを計算します (すべての入力値の差がゼロの場合、i/j/k の値は「正しい」)
私はこれを機能させています (Python と PyCL を使用して記述されています。コードは hereです)。
私の問題は、4 つの読み取り専用バッファー (入力値用に 3 つ、期待値用に 1 つ) がありますが、i/j/k の組み合わせごとに個別の「スコア」バッファーが必要です。
もう 1 つの問題は、実効的にシングルスレッドであるため、RMS 計算が最も遅い部分であることです (「スコア」のすべての値を合計し、合計を sqrt() で計算します)。
基本的に、そのようなプログラムを構成する賢明な方法があるかどうか疑問に思っています。
これは OpenCL に適したタスクのようです。私の目標の説明が複雑すぎないことを願っています。前述のように、私の現在のコードは hereです。より明確な場合、これは私がやろうとしていることの Python バージョンです。
import sys
import math
import random
def make_test_data(w = 128, h = 128):
in_r, in_g, in_b = [], [], []
print "Make raw data"
for x in range(w):
for y in range(h):
in_r.append(random.random())
in_g.append(random.random())
in_b.append(random.random())
# the unknown values
mtx = [random.random(), random.random(), random.random()]
print "Secret numbers were: %s" % mtx
out_r = [(r*mtx[0] + g*mtx[1] + b*mtx[2]) for (r, g, b) in zip(in_r, in_g, in_b)]
return {'in_r': in_r, 'in_g': in_g, 'in_b': in_b,
'expected_r': out_r}
def score_matrix(ir, ig, ib, expected_r, mtx):
ms = 0
for i in range(len(ir)):
val = ir[i] * mtx[0] + ig[i] * mtx[1] + ib[i] * mtx[2]
ms += abs(val - expected_r[i]) ** 2
rms = math.sqrt(ms / float(len(ir)))
return rms
# Make random test data
test_data = make_test_data(16, 16)
lowest_rms = sys.maxint
closest = []
divisions = 10
for possible_r in range(divisions):
for possible_g in range(divisions):
for possible_b in range(divisions):
pr, pg, pb = [x / float(divisions-1) for x in (possible_r, possible_g, possible_b)]
rms = score_matrix(
test_data['in_r'], test_data['in_g'], test_data['in_b'],
test_data['expected_r'],
mtx = [pr, pg, pb])
if rms < lowest_rms:
closest = [pr, pg, pb]
lowest_rms = rms
print closest