Python 如何构造这个OpenCL暴力代码
我刚刚开始使用OpenCL,我一直在研究如何以一种合理有效的方式构造程序(主要是避免大量数据从GPU传输到GPU或任何正在进行工作的地方) 我想做的是,考虑到:Python 如何构造这个OpenCL暴力代码,python,algorithm,opencl,brute-force,Python,Algorithm,Opencl,Brute Force,我刚刚开始使用OpenCL,我一直在研究如何以一种合理有效的方式构造程序(主要是避免大量数据从GPU传输到GPU或任何正在进行工作的地方) 我想做的是,考虑到: v = r*i + b*j + g*k …我知道r、g和b的各种值的v,但是I、j和k是未知的。我想通过蛮力计算I/j/k的合理值 换句话说,我有一堆“原始”RGB像素值,我有这些颜色的去饱和版本。我不知道用于计算去饱和值的权重(I/j/k) 我最初的计划是: 将数据加载到CL缓冲区(以便输入r/g/b值和输出) 有一个内核,它接受
v = r*i + b*j + g*k
…我知道r
、g
和b
的各种值的v
,但是I
、j
和k
是未知的。我想通过蛮力计算I
/j
/k
的合理值
换句话说,我有一堆“原始”RGB像素值,我有这些颜色的去饱和版本。我不知道用于计算去饱和值的权重(I/j/k)
我最初的计划是:
v=r*i+b*j+g*k
,将v
的值减去已知值,并将其存储在“分数”缓冲区中
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
导入系统
输入数学
随机输入
def制造测试数据(w=128,h=128):
in_r,in_g,in_b=[],[],[]
打印“生成原始数据”
对于范围(w)内的x:
对于范围(h)内的y:
in\u r.append(random.random())
in_g.append(random.random())
in_b.append(random.random())
#未知值
mtx=[random.random(),random.random(),random.random()]
打印“机密号码为:%s”%mtx
out_r=[(r*mtx[0]+g*mtx[1]+b*mtx[2]),用于(r,g,b)压缩(in_r,in_g,in_b)]
返回{'in_r':in_r,'in_g':in_g,'in_b':in_b,
'expected\u r':out\u r}
def分数矩阵(ir、ig、ib、预期值、mtx):
ms=0
对于范围内的i(len(ir)):
val=ir[i]*mtx[0]+ig[i]*mtx[1]+ib[i]*mtx[2]
ms+=abs(val-预期值[i])**2
rms=数学sqrt(ms/float(len(ir)))
返回rms
#随机抽取测试数据
测试数据=制作测试数据(16,16)
最低有效值=sys.maxint
最近的=[]
分区=10
对于可能的范围内(分区):
对于可能的范围内(分区):
对于范围内可能的_b(分区):
pr,pg,pb=[x/float(divisions-1)表示x英寸(可能的、可能的、可能的)]
rms=得分矩阵(
测试数据['in_r']、测试数据['in_g']、测试数据['in_b'],
测试数据['expected_r'],
mtx=[pr、pg、pb])
如果rms<最低值_rms:
最近的=[pr,pg,pb]
最低有效值=有效值
打印最近的
i、j、k集是独立的吗?我想是的。很少有事情会影响你的表现:
int i = get_thread_id(0);
float my_sum = 0;
for (; i < array_size; i += get_local_size(0)){
float val = in_r[i] * mtx_r + in_g[i] * mtx_g + in_b[i] * mtx_b;
my_sum += pow(fabs(expect_r[i] - val), 2);
}
inti=get\u thread\u id(0);
浮动我的总和=0;
对于(;i
或者,如果您需要按顺序计算i、j、k,您可以在OpenCL规范中查找barrier和memory fence函数,这样您就可以使用它们而不是运行两个内核,只需记住在第一步中总结所有内容,写入全局同步所有线程,然后再次总结有两个潜在问题:
i、j、k
值的求值来解决的问题pyopencl.array.sum(array)
进一步了解这是如何在原始OpenCL中实现的,苹果的OpenCL文档包括一个并行的sum缩减。与您想做的事情最相关的部分是。“运行太多小内核”的
main
和create\u reduction\u pass\u counts
函数