OpenCL で扱える SIMD の vector 型は、float4 や int4 といった型名表記に
なっています。この点は HLSL と同じです。
GLSL では vec4 や ivec4 等の独自の型が用いられていました。
また GLSL の場合 1コンポーネントの vec1 型は無く vec2~vec4 のみ。
OpenCL の仕様をよく見ると、最大 16要素まで扱えるものの使える組み合わせは
2, 4, 8, 16 だけです。つまり float1 も float3 もありません。
GLSL (float) vec2 vec3 vec4 OpenCL (float) float2 - float4 float8 float16 HLSL float1 float2 float3 float4
Compute Shader で用いられる HLSL では float1~float4 すべて使えます。
もともと vector<> の別名にすぎず、1~4 まで任意の数値を与えることができます。
つまり下記の定義と同じです。
typedef vector
また float v; と宣言した場合の v.x が許されるのも HLSL 独自かもしれません。
OpenCL は要素数が増えているため、swizzle も xyzw だけでなく s 表記が
追加されています。(rgba は無し)
float16 v; v.s0 // == v.x v.s1 // == v.y v.s2 // == v.z v.s3 // == v.w v.s4 ~ v.se v.sf
例えば v.xy は v.s01 と記述可能。float16 の全要素代入を明示的に書くなら
float16 d, s; d.s0123456789abcdef = s.s0123456789abcdef;
逆順にするなら
d.s0123456789abcdef = s.sfedcba9876543210;
float16 を 4×4 matrix とみなすなら Transpose (転置) は
d.s0123456789abcdef = s.s048c159d26ae37bf;
と書けます。
値数は括弧表記で、コンストラクタではなくキャストが付きます。
float16 d= (float16)(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
すべて同じ値ならスカラーからの変換が使えて d= (float16)(0); と書けます。
スカラー以外は個数が一致する必要があります。
float4 a= (float4)( 1.0f ); float16 d= (float16)( a, a, a, a ); float16 e= (float16)( (float8)(1.0f), (float8)(2.0f) );
一つ下のサイズの vector を取り出す suffix もあります。odd, even, lo, hi
float16 a= (float16)(1); float8 b= a.odd; //== a.s13579bdf float4 c= b.odd; //== b.s1357 float2 d= c.odd; //== c.s13 == c.yw float8 l= a.lo; //== a.s01234567 float8 h= a.hi; //== a.s89abcdef float4 ll= a.lo.lo; //== (a.s01234567).s0123 == a.s0123
おそらく特定の swizzle の別名です。
s 表記でも書けます。a.s01234567.s1357.s01 (== a.lo.odd.lo)
opencl-1.0.43 には 4×4 Transpose の応用例が載っています。
・KHRONOS GROUP OpenCL
・Khronos OpenCL API Registry
opencl-1.0.43.pdf page 134
//transpose t.even = x.lo; t.odd = x.hi; x.even = t.lo; x.odd = t.hi;
x t はどちらも float16。
展開してみます。
t.s02468ace = x.s01234567; t.s13579bdf = x.s89abcdef; // t: 0 1 2 3 4 5 6 7 <= x.lo // 8 9 a b c d e f <= x.hi // t= 08192a3b4c5d6e7f x.s02468ace = t.s01234567; x.s13579bdf = t.s89abcdef; // x: 0 8 1 9 2 a 3 b <= t.lo // 4 c 5 d 6 e 7 f <= t.hi // x= 048c159d26ae37bf
なんだか SSE のプログラムを見ているようです。
1行で記述できるのにこのような例が載っているということは、
Larrabee のプログラミングはこんな感じなのかもしれません。
GPU べったりのシェーダーとはまた違った印象です。
関連エントリ
・ATI Stream SDK 2.0 beta と OpenCL