OpenCLスカラー型の詳細については「Section 17.2.1, “組み込みスカラデータ型”」を参照ください。
PyOpenCLのScalarデータ型は、numpy.dtypeとOpenCLデータ型を組み入れており、各データ型は直感的にマップされています。
主なOpenCL-PyOpenCL間のデータのマッピングは以下のようになります。
OpenCLではベクトル型という、複数の要素を持つ変数を宣言することができます。
例えばfloat2であれば、2つの要素を持つ浮動小数点数、int4であれば4つの要素を持つ符号付き32bit整数となります。
これらのOpenCL組み込みベクトル型についてPyOpenCLではvecクラスで定義されています。
class pyopencl.array.vec
ベクトル型の使用方法ですが、一番手っ取り早いのがmake_「type」関数です。
以下のコードではfloat4のデータ型を持つ変数を初期化しています。
a_vec4 = pyopencl.array.vec.make_float4(0.0, 0.0, 1.0, 0.0)
しかしnumpyのreshape関数を使いこなしている読者からすると用途が見えてこないかもしれません。
ベクトル型は本書第二部で解説するSIMDレーンを有効活用する効用があるのですが、詳細については第二部に譲りたいと思います。
CLArrayTest.py.
import numpy as np
import pyopencl as cl
import pyopencl.array as clarr
import warnings
import os
os.environ['PYOPENCL_COMPILER_OUTPUT'] = '1'
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]).astype(np.float32)
b = np.array([10, 20, 30, 40, 50,
60, 70, 80, 90, 100]).astype(np.float32)
platforms = cl.get_platforms()
ctx = cl.Context([platforms[0].get_devices(cl.device_type.GPU)[0]])
queue = cl.CommandQueue(ctx)
from pyopencl.clrandom import rand as clrand
with warnings.catch_warnings():
warnings.simplefilter("ignore")
a_gpu = clarr.to_device(queue, a)
b_gpu = clarr.to_device(queue, b)
a_gpu = clarr.Array(queue, (10,), dtype=clarr.vec.float4)
a_gpu.fill(clarr.vec.make_float4(0.0, 0.0, 1.0, 0.0))
a = a_gpu.get()
print(a)
上記のプログラムの出力は以下のようになります。
出力.
/Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 /Users/komatsu/PycharmProjects/MyPythonProject/CLArrayTest.py [(0.0, 0.0, 1.0, 0.0) (0.0, 0.0, 1.0, 0.0) (0.0, 0.0, 1.0, 0.0) (0.0, 0.0, 1.0, 0.0) (0.0, 0.0, 1.0, 0.0) (0.0, 0.0, 1.0, 0.0) (0.0, 0.0, 1.0, 0.0) (0.0, 0.0, 1.0, 0.0) (0.0, 0.0, 1.0, 0.0) (0.0, 0.0, 1.0, 0.0)]
OpenCL1.2は複素数をサポートしていませんが、PyOpenCLのArrayパッケージでは複素数をnumpyのように宣言することを可能としています。
CLComplexTest.py.
from __future__ import print_function
import numpy as np
import pyopencl as cl
from pyopencl import array as clarr
import warnings
import os
os.environ['PYOPENCL_COMPILER_OUTPUT'] = '1'
platforms = cl.get_platforms()
ctx = cl.Context([platforms[0].get_devices(cl.device_type.GPU)[0]])
queue = cl.CommandQueue(ctx)
with warnings.catch_warnings():
warnings.simplefilter("ignore")
ary = clarr.Array(queue, shape=(10,), dtype=np.float32).astype(np.complex64)
with warnings.catch_warnings():
warnings.simplefilter("ignore")
host_ary = (ary + np.complex64(1+1j)).get()
print(host_ary)
上記のプログラムの出力は以下のようになります。
/Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 /Users/komatsu/PycharmProjects/MyPythonProject/CLComplexTest.py [ 1.+1.j 1.+1.j 1.+1.j 1.+1.j 1.+1.j 1.+1.j 1.+1.j 1.+1.j 1.+1.j 1.+1.j]
Copyright 2018-2019, by Masaki Komatsu