简体   繁体   English

结构的 VexCL 向量?

[英]VexCL vector of structs?

So I know that it is possible to use custom types with OpenCL.所以我知道可以在 OpenCL 中使用自定义类型。 But I haven't been able to use them with VexCL.但是我无法将它们与 VexCL 一起使用。 Creating a device vector of structs works fine, but I can't perform any operations.创建结构的设备向量工作正常,但我无法执行任何操作。

As I haven't found any examples using custom types with VexCL my question is is that even possible?由于我还没有找到任何使用 VexCL 的自定义类型的例子,我的问题是这可能吗? Thanks in advance.提前致谢。

VexCL does not support operations with vectors of structs out of the box. VexCL 不支持开箱即用的结构向量操作。 You will need to help it a bit.你需要帮助它一点。 First, you need to tell VexCL how to spell the type name of the struct.首先,您需要告诉 VexCL 如何拼写结构的类型名称。 Let's say you have the following struct defined on the host side:假设您在主机端定义了以下结构:

struct point2d {
    double x;
    double y;
};

You need to provide a specification of the vex::type_name_impl struct that will generate a string corresponding to the type name of the struct.您需要提供vex::type_name_impl结构的规范,它将生成与结构的类型名称相对应的字符串。 Remember that the code you are generating is C99:请记住,您生成的代码是 C99:

namespace vex {
    template <> struct type_name_impl<point2d> {
        static std::string get() { return "struct point2d"; }
    };
}

You will also need to make sure every generated kernel knows about your struct.您还需要确保每个生成的内核都知道您的结构。 This may be achieved with vex::push_program_header() function after the VexCL context has been initialized:这可以在 VexCL 上下文初始化后使用 vex ::push_program_header()函数实现:

vex::push_program_header(ctx, "struct point2d { double x; double y; };");

This will allow you to declare vectors of the struct, and to pass the vectors to custom functions.这将允许您声明结构的向量,并将向量传递给自定义函数。 That should be general enough.这应该足够通用了。 Here is the complete example:这是完整的示例:

#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;
}

And here is the kernel that will be generated for the assignment operation of y = dist(x);这是将为y = dist(x);的赋值操作生成的内核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] );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM