LoginSignup
17
13

More than 5 years have passed since last update.

C/C++で他のファイルをincludeして文字列として埋め込む方法(OpenCLとか)

Posted at

例えばOpenCLを使う時、ソースコードを文字列として実行時にコンパイラに渡しますが、それだと

  • .clを別ファイルとして毎回ファイル読み込みする
  • .clをリソースファイルとして埋め込む(Windowsの場合)
  • 諦めてソースコード中に文字列として直書きする

という辺りが一般的ですが、それもちょっとイマイチです。

で、以前のアドベントカレンダーで @tap4453 さんが『マクロを使って便利にOpenCL』という記事を書いていたのですが、そのままだとうまくいかなかったので、私の使い方をメモしておきます。

device.cl
#ifndef OCL_EXTERNAL_INCLUDE
#define OCL_EXTERNAL_INCLUDE(x) x
#endif

OCL_EXTERNAL_INCLUDE(
kernel void func(global double dst[])
{
    const int i = get_global_id(0);
    dst[i] = i*i;
}
)
host.cpp
#define OCL_EXTERNAL_INCLUDE(x) #x
const char srcStr[] =
#include "ocl.cl"
;

cl::Program::Sources sources;
sources.push_back(std::make_pair(srcStr, std::strlen(srcStr)));
cl::Program program(context, sources);
program.build(devices);

としておくと、srcStrが文字列としてdevice.clの内容を持ってくれます。
文字列の長さはstd::strlenでとれますね。

OpenCL関係なくても、別のファイルを埋め込めるのは地味に便利です(UIテキストとか計算の入力値とか)。
C++で書きましたがCでも同じはず・・・。

ほんとに出来るのか試したい人はbitbucketに実際の使用例が置いてあるのでご覧ください。

ちなみに、「OpenCLはCUDAと違ってソースコードを文字列で持つのが嫌!」みたいなのたまに聞きますが、逆に最適化極めたい場合は実行時にソースコードを変更したり生成できたりするので、これはこれで利点だと思ってます。
ViennaCLなんかは、計算式は式テンプレートで持っておいて、コンパイルするカーネルはそれぞれ最適な感じで生成しますしね。

17
13
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
13