Я пытаюсь написать код для преобразования массива родного типа C++ в векторный тип соответствующего размера, определенный стандартом OpenCL.Как лучше обрабатывать тип члена класса, который зависит от параметров шаблона?
Endian-ness и упаковка имеют специфическую реализацию OpenCL. Типы OpenCL не обеспечивают удобный оператор []. (на самом деле 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;
}
}
};
Возможно, вам будет интересно узнать, как я буду использовать этот класс. В одном примере у меня есть шаблон templated для типа 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;
};
В getDescriptorStruct()
упаковывает OpenCL поддерживается типа таким образом, что я могу послать к API OpenCL в качестве аргумента ядра с всеми байтами падения в нужном месте.
Если кто-то думает о смене парадигмы, мне только понадобится установить весь вектор сразу.
Ссылка на спецификацию типа OpenCL. http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/vectorDataTypes.html – NoahR