日別アーカイブ: 2009年8月14日

OpenCL の vector 型

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 float4;

また 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