PyOpenCLでもMapReduceを部分的に実装したReductionKernelクラスを提供しています。
PyOpenCLの組み込み関数を使えばMapReduceの実装は簡単です。しかしパフォーマンスペナルティを考慮すれば、PyOpenCL組み込みの演算機能を使うのは推奨できません。
class pyopencl.reduction.ReductionKernel( ctx, dtype_out, #(1) neutral, reduce_expr, #(2) map_expr=None, #(3) arguments=None, #(4) name="reduce_kernel", options=[], preamble="")
参考までに以下に実装例を掲載します。
CLReductionKernelTest.py.
from pyopencl.reduction import ReductionKernel import numpy as np import pyopencl as cl import pyopencl.array as clarr ctx = cl.Context(cl.get_platforms()[0].get_devices(cl.device_type.GPU)) queue = cl.CommandQueue(ctx) a = clarr.arange(queue, 10, dtype=np.uint32) b = clarr.arange(queue, 10, dtype=np.uint32) reduction_kernel = ReductionKernel( ctx, np.uint32, neutral="0", reduce_expr="a+b", map_expr="x[i]+y[i]", arguments="__global uint* x, __global uint* y" ) result = reduction_kernel(a, b).get() print(result) reduction_kernel_product = ReductionKernel( ctx, np.uint32, neutral="0", reduce_expr="a+b", map_expr="x[i]*y[i]", arguments="__global uint* x, __global uint* y" ) result = reduction_kernel_product(a, b).get() print(result) reduction_kernel_single = ReductionKernel( ctx, np.uint32, neutral="0", reduce_expr="a+b", map_expr="x[i]", arguments="__global uint* x" ) result = reduction_kernel_single(a).get() print(result)
上記のプログラムの出力は以下のようになります。
出力.
/Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 /Users/komatsu/PycharmProjects/MyPythonProject/CLReductionKernelTest.py 90 285 45
この実装例では3つのMapReduceのパターンに倣っています。まずMap時に変数を乗算するパターンです。
これは以下のような引数指定をします。
reduce_expr="a+b", map_expr="x[i]*y[i]"
Map表現に乗算、Reduce表現に加算を指定します。Map時に変数を加算するパターンは次のようにします。
reduce_expr="a+b", map_expr="x[i]+y[i]"
最後にMap表現を一つの変数とすると、シンプルにReductionパターンを計算します。
reduce_expr="a+b", map_expr="x[i]"
出力結果は45となり、x[i](1,2,3,…,9)の和と一致します。
Copyright 2018-2019, by Masaki Komatsu