ネイティブ C++ 型の配列を、OpenCL 標準で定義された適切なサイズのベクトル型に変換するコードを作成しようとしています。
エンディアンとパッキングは OpenCL 実装固有です。OpenCL 型は便利な operator[] を提供しません。(実際には API は C です) 別の問題:メンバーはありますが、cl_int4
ありません。.s3
cl_int2
機能的には機能するものがありますが、テンプレートのクレイジーな土地に迷い込んでしまったことがわかります。
これをより良い方法で行うことはできますか? これらの関数は頻繁には呼び出されないため、プログラムのバイナリ サイズを小さくし、ソース コードを短くすることを組み合わせた方がよいでしょう。
これが私がこれまでに得たものです。すべての次元の特殊化 (3 ~ 6 を省略) を示しているわけではなく、少なくとも整数型についても実装したいと考えています。
#include <CL/cl.h>
template < typename HOST_T, int NUM_DIM >
struct Payload_t;
// Vector length needs to be (for dims 1-6): 2, 4, 8, 8, 16, 16
//single precision
template < >
struct __attribute__((packed)) Payload_t <float, 1> {
cl_float2 vec;
void setElement( int pos, float value )
{
switch (pos) {
case 0: vec.s0 = value; return;
case 1: vec.s1 = value; return;
default: return;
}
}
};
template < >
struct __attribute__((packed)) Payload_t <float, 2> {
cl_float4 vec;
void setElement( int pos, float value )
{
switch (pos) {
case 0: vec.s0 = value; return;
case 1: vec.s1 = value; return;
case 2: vec.s2 = value; return;
case 3: vec.s3 = value; return;
default: return;
}
}
};
/// double-precision
template < >
struct __attribute__((packed)) Payload_t <double, 1> {
cl_double2 vec;
void setElement( int pos, double value )
{
switch (pos) {
case 0: vec.s0 = value; return;
case 1: vec.s1 = value; return;
default: return;
}
}
};
template < >
struct __attribute__((packed)) Payload_t <double, 2> {
cl_double4 vec;
void setElement( int pos, double value )
{
switch (pos) {
case 0: vec.s0 = value; return;
case 1: vec.s1 = value; return;
case 2: vec.s2 = value; return;
case 3: vec.s3 = value; return;
default: return;
}
}
};
このクラスをどのように使用するのか興味があるかもしれません。1 つの例では、次のメンバー クラスのインスタンスを持つ REAL 型でテンプレート化されたクラスがあり、その中に のインスタンスがありますPayload_t
。
template <int NUM_DIM >
struct cartesian_box_descriptor_t : cartesian_box_descriptor_base_t
{
static const int vectorLengthArray[6];
void set_dx( REAL * dx_vec )
{
for (int i = 0; i < NUM_DIM; ++i)
payload.setElement( i, dx_vec[i] );
};
void set_startx( REAL * startx_vec )
{
for (int i = 0; i < NUM_DIM; ++i)
payload.setElement( NUM_DIM + i , startx_vec[i] );
};
virtual WxAny getDescriptorStruct() const
{
return WxAny( payload ); // packages this simple structure as 'scalar' with hidden type
};
Payload_t< REAL, NUM_DIM> payload;
};
OpenCL がサポートするgetDescriptorStruct()
パッケージは、すべてのバイトが適切な場所に配置されたカーネル引数として OpenCL API に送信できる方法で型をサポートします。
誰かがパラダイム シフトについて考えている場合、ベクトル全体を一度に設定するだけで済みます。