2

したがって、OpenCL でカスタム型を使用できることはわかっています。しかし、私はそれらを VexCL で使用できませんでした。構造体のデバイス ベクターの作成は正常に機能しますが、操作を実行できません。

VexCL でカスタム タイプを使用する例を見つけられなかったので、私の質問はそれが可能でしょうか? 前もって感謝します。

4

1 に答える 1

1

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] );
  }
}
于 2015-06-15T18:09:25.127 に答える