VexCL中的结构体向量?

3

我知道在OpenCL中可以使用自定义类型。但是我无法在VexCL中使用它们。创建一个结构体的设备向量是可行的,但我无法执行任何操作。

由于我没有找到任何使用自定义类型的VexCL示例,所以我的问题是:这是否可能?谢谢。


你尝试过什么吗?有写过代码吗? - jabujavi
1个回答

2

VexCL默认不支持直接对结构体向量进行操作。需要进行一些设置。首先,您需要告诉VexCL如何拼写结构体的类型名称。假设您在主机端定义了以下结构体:

struct point2d {
    double x;
    double y;
};

你需要提供vex::type_name_impl结构的规范,以生成对应于该结构类型名称的字符串。请记住,您正在生成的代码是C99:
namespace vex {
    template <> struct type_name_impl<point2d> {
        static std::string get() { return "struct point2d"; }
    };
}

你还需要确保每个生成的内核都知道你的结构体。在VexCL上下文初始化后,可以通过vex::push_program_header()函数来实现这一点:
vex::push_program_header(ctx, "struct point2d { double x; double y; };");

这将允许您声明结构体的向量,并将向量传递给自定义函数。这应该足够通用。以下是完整示例:
#include <vexcl/vexcl.hpp>

// Host-side definition of the struct.
struct point2d {
    double x, y;
};

// We need this for code generation.
namespace vex {
    template <>
    struct type_name_impl<point2d> {
        static std::string get() { return "struct point2d"; }
    };
}

int main() {
    const size_t n = 16;

    vex::Context ctx(vex::Filter::Env);
    std::cout << ctx << std::endl;

    // After this, every kernel will have the struct declaration in header:
    vex::push_program_header(ctx, "struct point2d { double x; double y; };");

    // Now we may define vectors of the struct:
    vex::vector<point2d> x(ctx, n);
    vex::vector<double>  y(ctx, n);

    // We won't be able to use the vectors in any expressions except for
    // custom functions, but that should be enough:
    VEX_FUNCTION(point2d, init, (double, x)(double, y),
            struct point2d p = {x, y}; return p;
            );

    VEX_FUNCTION(double, dist, (point2d, p),
            return sqrt(p.x * p.x + p.y * p.y);
            );

    x = init(3,4);
    y = dist(x);

    std::cout << y << std::endl;
}

这里是生成赋值操作y = dist(x);的内核:

struct point2d { double x; double y; };
double dist
(
  struct point2d p
)
{
  return sqrt(p.x * p.x + p.y * p.y);
}
kernel void vexcl_vector_kernel
(
  ulong n,
  global double * prm_1,
  global struct point2d * prm_2
)
{
  for(ulong idx = get_global_id(0); idx < n; idx += get_global_size(0))
  {
    prm_1[idx] = dist( prm_2[idx] );
  }
}

哇,非常感谢,这正是我在寻找的。明天我会试一下。 - Frodo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接