目次: OpenCL
OpenCLは複数のベンダーのデバイスを同時に扱うことができます。ICD(Installable Client Driver)というそうです。ICDはGPUなどのデバイスを制御し、アプリケーションとICDの間にICDローダーが存在します。
Debian TestingではICDローダーとしてocl-icd-2.2.12が使われています。
$ apt-cache search ocl-icd-libopencl1 ocl-icd-libopencl1 - Generic OpenCL ICD Loader
ローダーのソースコードはGitHub(リンク)にあります。
先程、図示したもの以外にもICDはいくつか実装があります。現時点のDebian Testingでは下記が提供されていました。
IntelはICDのソースコードを完全にオープンにしています。NVIDIAは公開していません。AMDもないのかな?
動作を追ってみたいと思います。アプリケーションにはclinfoを使います。ocl-icdは環境変数OCL_ICD_DEBUG=15に設定すると、動作時に詳細なログを出力します。デバッガで追うのと併用するとわかりやすいです。
ローダーが走査するディレクトリは /etc/OpenCL/vendorsがハードコードされていますが、環境変数OPENCL_VENDOR_PATHで変更できます。
ICDのロードの中心となる処理は _find_and_check_platforms() です。
プラットフォームは説明が難しいですが、OpenCL APIの実体+任意のドライバ固有のデータとでも言いましょうか。変数の型はcl_platform_id * 型です。cl_platform_idは少なくとも先頭のメンバはstruct _cl_icd_dispatch *dispatchでなければなりません。dispatchの後ろには他の情報が入っていても問題ないようです。
// ocl-icd/ocl_icd_loader.c
static inline void _find_and_check_platforms(cl_uint num_icds) {
cl_uint i;
...
cl_platform_id *platforms = (cl_platform_id *) malloc( sizeof(cl_platform_id) * num_platforms);
error = (*plt_fn_ptr)(num_platforms, platforms, NULL);
...
for(j=0; j<num_platforms; j++) {
debug(D_LOG, "Checking platform %i", j);
struct platform_icd *p=&_picds[_num_picds];
char *param_value=NULL;
p->extension_suffix=NULL;
p->vicd=&_icds[i];
p->pid=platforms[j]; //★★pid = platform IDのことらしい
/* If clGetPlatformInfo is not exported and we are here, it
* means that OCL_ICD_ASSUME_ICD_EXTENSION. Si we try to take it
* from the dispatch * table. If that fails too, we have to
* bail.
*/
if (plt_info_ptr == NULL) {
plt_info_ptr = p->pid->dispatch->clGetPlatformInfo; //★★dispatchメンバが存在することを前提としている
// ocl-icd/khronos-headers/CL/cl.h
typedef struct _cl_platform_id * cl_platform_id;
// ocl-icd/(build-dir)/ocl_icd_loader_gen.h
struct _cl_platform_id { struct _cl_icd_dispatch *dispatch; }; //★★dispatch以外は特に規定がなさそう
// ocl-icd/(build-dir)/ocl_icd.h
struct _cl_icd_dispatch {
#ifdef CL_VERSION_1_0
CL_API_ENTRY cl_int (CL_API_CALL*clGetPlatformIDs)(
cl_uint /* num_entries */,
cl_platform_id * /* platforms */,
cl_uint * /* num_platforms */
) CL_API_SUFFIX__VERSION_1_0;
#else
CL_API_ENTRY cl_int (CL_API_CALL* clUnknown0)(void);
#endif
#ifdef CL_VERSION_1_0
CL_API_ENTRY cl_int (CL_API_CALL*
clGetPlatformInfo)(
cl_platform_id /* platform */,
cl_platform_info /* param_name */,
size_t /* param_value_size */,
void * /* param_value */,
size_t * /* param_value_size_ret */
) CL_API_SUFFIX__VERSION_1_0;
#else
CL_API_ENTRY cl_int (CL_API_CALL* clUnknown1)(void);
#endif
...
//★★こんな調子で関数ポインタの定義が延々と続く
先頭のdispatchはたくさんの関数ポインタが並んだ巨大な構造体です。アプリケーションから見るとOpenCLのAPIはocl-icdが提供しているように見えますが、ocl-icdのAPI実装はdispatchの関数ポインタを呼ぶラッパー関数であり、関数ポインタと、OpenCL API実装の本体を提供するのは各ICDの役割です。
< | 2020 | > | ||||
<< | < | 07 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 | - |
合計:
本日:
管理者: Katsuhiro Suzuki(katsuhiro( a t )katsuster.net)
This is Simple Diary 1.0
Copyright(C) Katsuhiro Suzuki 2006-2023.
Powered by PHP 8.2.15.
using GD bundled (2.1.0 compatible)(png support.)