link もっと前
   2020年 7月 22日 -
      2020年 7月 13日  
link もっと後

link 未来から過去へ表示(*)
link 過去から未来へ表示

link permalink

link 編集する

ARM SBC リスト

最近はたくさんの ARM のシングルボードコンピュータ(SBC)が市販されています。2019年以降のボードも追加してみました。値段は変動するので参考です。

Amlogic S905X3
ボード Hardkernel ODROID-C4, A55/2.0GHz x 4, 4GB DDR4-2666, 12nm, $50, 2020/04
Amlogic S912
ボード Khadas KVIM2-M-002, A53/1.5GHz x 8, 3GB DDR4-????, 28nm, $170, 2017/08
Broadcom BCM2711
ボード Raspberry Pi 4 Model B, A72/1.5GHz x 4, 8GB LPDDR4, 28nm, $75, 2019/11
HiSilicon Kirin 970
ボード 96boards HiKey 970, A73/2.36GHz x 4, A53/1.8GHz x 4, 6GB LPDDR4-1866, 10nm, $299, 2018/??
MediaTek Helio X20
ボード 96boards MediaTek X20, A72/2.1GHz x 2, A53/1.85GHz x 4, A53/1.4GHz x 4, 2GB LPDDR3-????, 20nm, $199, 2017/??
NVIDIA Xavier AGX
ボード NVIDIA Jetson Xavier AGX, Carmel/2.26GHz x 8, 8MB L2, 4MB L3, 32GB LPDDR4-2133, 12nm, $700, 2020/??
NVIDIA Xavier NX
ボード NVIDIA Jetson Xavier NX, Carmel/1.4GHz x 6, 6MB L2, 4MB L3, 8GB LPDDR4-1600, 12nm, $400, 2020/??
Rockchip RK3399
ボード FriendlyARM NanoPC-T4, A72/2GHz x 2, A53/1.5GHz x 4, 4GB LPDDR3-1866, $109, 2018/??
Samsung S5P6818
ボード FriendlyARM NanoPC-T3 Plus, A53/1.4GHz x 8, 2GB DDR3, $75, 2018/??

古い世代の SoC を採用したボード達です。

AllWinner H6
ボード PINE64 PINE H64, A53 x 4, 2GB LPDDR3-1600, $36
AllWinner H5
ボード FriendlyARM NanoPi NEO2, A53/1.5GHz x 4, 1GB DDR3, $20
Amlogic S905
ボード Hardkernel ODROID-C2, A53/1.5GHz x 4, 2GB DDR3-1866? (912MHz), 28nm, $39
Broadcom BCM2837B
ボード Raspberry Pi 3 Model B, A53/1.2GHz x 4, 1GB LPDDR2, 28nm, $35
HiSilicon Kirin 960
ボード HiKey 960, A72 x 4, A53 x 4, 3GB LPDDR4, 16nm FinFET, $239
NVIDIA Tegra X2 (Parker)
ボード Jetson TX2, Denver/2GHz x 2, A57/2GHz x 4, 8GB LPDDR4, 16nm, $600
NVIDIA Tegra X1
ボード Jetson TX1, A57/1.9GHz x 4, 4GB LPDDR4, 20nm, $500
Rockchip RK3328
ボード PINE64 ROCK64, A53/1.4GHz x 4, 4GB LPDDR3-1866, $24.95 (1GB) $34.95 (2GB) $44.95 (4GB)

以前(2019年 5月 15日の日記参照)載せた情報も含んでいます。

[編集者: すずき]
[更新: 2020年 7月 23日 01:55]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

link 編集する

GCC を調べる - その 18 - ベクトル Not 演算の定義

目次: GCC を調べる - まとめリンク

前回(2020年 7月 19日の日記参照)は四則演算と論理演算(and, or, xor)を定義しました。今回は Not 演算を定義します。他の論理演算と異なり、Not 演算は 2オペランドしか取りませんから、define_insn を別に書く必要があります。

ベクトル Not 演算の定義

;; gcc/config/riscv/riscv.md

(define_insn "one_cmpl<mode>2"
  [(set (match_operand:ANYV           0 "register_operand" "=v")
	(not:ANYV (match_operand:ANYV 1 "register_operand" "%v")))]
  "TARGET_VECTOR"
  "vnot.vt%0,%1"
  [(set_attr "type" "logical")
   (set_attr "vecmode" "<MODE>")])

前回同様に、ベクトル拡張記法(Vector Extensions (Using the GNU Compiler Collection (GCC)))を使ってビット毎 Not を使うプログラムを書きます。

ベクトル Not 演算のサンプルプログラム

typedef int __v64si __attribute__((__vector_size__(256)));

void test()
{
	__v64si v10, v11;
	static int b[1024 * 1024] = {0};

	__asm__ volatile ("vlw.v %0, %1\n" : "=&v"(v10) : "A"(b[10]));
	__asm__ volatile ("vlw.v %0, %1\n" : "=&v"(v11) : "A"(b[20]));

	v10 = ~v11;

	__asm__ volatile ("vsw.v %1, %0\n" : "=A"(b[40]) : "v"(v10));
}

コンパイルするとエラーが発生します。何かお気に召さないようです。

コンパイルエラー
$ riscv32-unknown-elf-gcc b.c -nostdlib -Og -march=rv32gcv -mabi=ilp32f

during RTL pass: reload
dump file: b.c.282r.reload
b.c: In function 'test':
b.c:14:1: internal compiler error: in setup_operand_alternative, at lra.c:814
   14 | }
      | ^
0xea5c36 setup_operand_alternative
        gcc/gcc/lra.c:814
0xea70c2 lra_set_insn_recog_data(rtx_insn*)
        gcc/gcc/lra.c:1073
0xea30f9 lra_get_insn_recog_data
        gcc/gcc/lra-int.h:488
0xeab0b9 remove_scratches_1
        gcc/gcc/lra.c:2058
0xeab4c4 remove_scratches
        gcc/gcc/lra.c:2094
0xeac629 lra(_IO_FILE*)
        gcc/gcc/lra.c:2396
0xe1a41f do_reload
        gcc/gcc/ira.c:5523
0xe1ae5c execute
        gcc/gcc/ira.c:5709

コードを見ると最後のオペランドに % を付けるべきではないそうです。確かに define_insn を見ると % が要らないのに付いています。

エラーを出している箇所

// gcc/lra.c

/* Setup info about operands in alternatives of LRA DATA of insn.  */
static void
setup_operand_alternative (lra_insn_recog_data_t data,
			   const operand_alternative *op_alt)
{
  int i, j, nop, nalt;
  int icode = data->icode;
  struct lra_static_insn_data *static_data = data->insn_static_data;

  static_data->commutative = -1;
  nop = static_data->n_operands;
  nalt = static_data->n_alternatives;
  static_data->operand_alternative = op_alt;
  for (i = 0; i < nop; i++)
    {
      static_data->operand[i].early_clobber_alts = 0;
      static_data->operand[i].is_address = false;
      if (static_data->operand[i].constraint[0] == '%')    //★★% が付いていれば commutative
	{
	  /* We currently only support one commutative pair of operands.  */
	  if (static_data->commutative < 0)
	    static_data->commutative = i;
	  else
	    lra_assert (icode < 0); /* Asm  */
	  /* The last operand should not be marked commutative.  */
	  lra_assert (i != nop - 1);    //★★このアサートに引っかかる
	}
    }

...

素直に応じるとエラーは消えます。

ベクトル演算の Not の定義(修正後)

(define_insn "one_cmpl<mode>2"
  [(set (match_operand:ANYV           0 "register_operand" "=v")
	(not:ANYV (match_operand:ANYV 1 "register_operand" " v")))]    ★★% を消す
  "TARGET_VECTOR"
  "vnot.vt%0,%1"
  [(set_attr "type" "logical")
   (set_attr "vecmode" "<MODE>")])

四則演算、論理演算(3オペランド系)と、Not 演算(2オペランド系)が揃いました。残りの頻出する演算はビットシフト系かな?

最後のオペランドを commutative にできない理由

最後のオペランドを commutative にしてはいけない理由は、GCC の Constraints の説明を見るとわかります。

`%' Declares the instruction to be commutative for this operand and the following operand. This means that the compiler may interchange the two operands if that is the cheapest way to make all operands fit the constraints. GCC can only handle one commutative pair in an asm; if you use more, the compiler may fail. Note that you need not use the modifier if the two alternatives are strictly identical; this would only waste time in the reload pass. The modifier is not operational after register allocation, so the result of define_peephole2 and define_splits performed after reload cannot rely on `%' to make the intended insn match.

難しいことを言っていますが、commutative は % を付けたオペランドと「次」のオペランドが可換だと宣言することだそうです。最後のオペランドには「次」のオペランドがありませんから、% を付けてはいけません。なるほど。

RISC-V の場合は論理演算の define_insn の 2番目のオペランドに % が使われています。

RISC-V スカラ論理演算の定義

;; gcc/config/riscv/riscv.md

;; This code iterator allows the three bitwise instructions to be generated
;; from the same template.
(define_code_iterator any_bitwise [and ior xor])

...

(define_insn "<optab><mode>3"
  [(set (match_operand:X                0 "register_operand" "=r,r")
	(any_bitwise:X (match_operand:X 1 "register_operand" "%r,r")
		       (match_operand:X 2 "arith_operand"    " r,I")))]
  ""
  "<insn>%i2t%0,%1,%2"
  [(set_attr "type" "logical")
   (set_attr "mode" "<MODE>")])

例えば and r1, r2, r3 と and r1, r3, r2 は結果が同じですから、2番目と 3番目のオペランドは入れ替え可能です。3つの論理演算(any_bitwise は and, or, xor のこと)はいずれも同様に入れ替え可能ですので、このような定義になっています。

[編集者: すずき]
[更新: 2020年 7月 23日 00:28]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

link 編集する

GCC を調べる - その 17 - ベクトル四則演算、論理演算の定義

目次: GCC を調べる - まとめリンク

ベクトルのロード、ストアだけでは自動ベクトル化できるコードが少なすぎるので、他の演算も定義したいと思います。

ベクトル演算の加算、減算、乗算、除算、論理演算(and, or, xor)の定義

;; gcc/config/riscv/riscv.md

(define_attr "vecmode" "unknown,V32SI,V64SI"
  (const_string "unknown"))

...

;; Iterator for hardware supported vector modes.
(define_mode_iterator ANYV [(V32SI "TARGET_VECTOR")
			    (V64SI "TARGET_VECTOR")])

...


;;★★加算

(define_insn "add<mode>3"
  [(set (match_operand:ANYV	       0 "register_operand" "=v")
	(plus:ANYV (match_operand:ANYV 1 "register_operand" " v")
		   (match_operand:ANYV 2 "arith_operand"    " v")))]
  "TARGET_VECTOR"
  "vadd.vvt%0,%1,%2"
  [(set_attr "type" "arith")
   (set_attr "vecmode" "<MODE>")])


;;★★減算

(define_insn "sub<mode>3"
  [(set (match_operand:ANYV		0 "register_operand" "=v")
	(minus:ANYV (match_operand:ANYV 1 "register_operand" " v")
		    (match_operand:ANYV 2 "arith_operand"    " v")))]
  "TARGET_VECTOR"
  "vsub.vvt%0,%1,%2"
  [(set_attr "type" "arith")
   (set_attr "vecmode" "<MODE>")])


;;★★乗算

(define_insn "mul<mode>3"
  [(set (match_operand:ANYV	       0 "register_operand" "=v")
	(mult:ANYV (match_operand:ANYV 1 "register_operand" " v")
		   (match_operand:ANYV 2 "arith_operand"    " v")))]
  "TARGET_VECTOR"
  "vmul.vvt%0,%1,%2"
  [(set_attr "type" "arith")
   (set_attr "vecmode" "<MODE>")])


;;★★除算

;; This code iterator allows unsigned and signed division to be generated
;; from the same template.
(define_code_iterator any_div [div udiv mod umod])

(define_insn "<optab><mode>3"
  [(set (match_operand:ANYV		  0 "register_operand" "=v")
	(any_div:ANYV (match_operand:ANYV 1 "register_operand" " v")
		      (match_operand:ANYV 2 "arith_operand"    " v")))]
  "TARGET_VECTOR"
  "v<insn>.vvt%0,%1,%2"
  [(set_attr "type" "arith")
   (set_attr "vecmode" "<MODE>")])


;;★★論理演算

;; This code iterator allows the three bitwise instructions to be generated
;; from the same template.
(define_code_iterator any_bitwise [and ior xor])

...

(define_insn "<optab><mode>3"
  [(set (match_operand:ANYV		      0 "register_operand" "=v")
	(any_bitwise:ANYV (match_operand:ANYV 1 "register_operand" "%v")
			  (match_operand:ANYV 2 "arith_operand"    " v")))]
  "TAREGET_VECTOR"
  "v<insn>.vvt%0,%1,%2"
  [(set_attr "type" "logical")
   (set_attr "vecmode" "<MODE>")])

四則演算、論理演算を使う下記のプログラムを書きます。自動ベクトル化で四則演算のループをベクトル化しても良いですが、ベクトル拡張記法(Vector Extensions (Using the GNU Compiler Collection (GCC)))を使ったほうが狙った演算が出しやすく、テストするときに楽です。

ベクトル四則演算、論理演算のサンプルプログラム

typedef int __v64si __attribute__((__vector_size__(256)));

void test()
{
	__v64si v10, v11, v12, v13;0;

	__asm__ volatile ("vlw.v %0, %1\n" : "=&v"(v10) : "A"(b[10]));
	__asm__ volatile ("vlw.v %0, %1\n" : "=&v"(v11) : "A"(b[20]));
	__asm__ volatile ("vlw.v %0, %1\n" : "=&v"(v12) : "A"(b[30]));
	__asm__ volatile ("vlw.v %0, %1\n" : "=&v"(v13) : "A"(b[40]));

	v10 = v11 + v12;
	v11 &= v12 - v13;
	v12 |= v13 * v10;
	v13 ^= v10 / v11;

	__asm__ volatile ("vsw.v %1, %0\n" : "=A"(b[40]) : "v"(v10));
	__asm__ volatile ("vsw.v %1, %0\n" : "=A"(b[50]) : "v"(v11));
	__asm__ volatile ("vsw.v %1, %0\n" : "=A"(b[60]) : "v"(v12));
	__asm__ volatile ("vsw.v %1, %0\n" : "=A"(b[70]) : "v"(v13));
}

ビルド方法は何でも良いですが、最適化レベルを Og にするとアセンブラが見やすいと思います。

ベクトル四則演算、論理演算のサンプルプログラム(逆アセンブル)
$ riscv32-unknown-elf-gcc b.c -nostdlib -g -Og -march=rv32gcv -mabi=ilp32f

$ riscv32-unknown-elf-objdump -dS a.out

...

        __asm__ volatile ("vlw.v %0, %1
" : "=&v"(v13) : "A"(b[40])); 10092: 0a028793 addi a5,t0,160 10096: 1207e207 vlw.v v4,(a5) v10 = v11 + v12; 1009a: 022081d7 vadd.vv v3,v2,v1 v11 &= v12 - v13; 1009e: 0a120057 vsub.vv v0,v1,v4 100a2: 26010057 vand.vv v0,v0,v2 v12 |= v13 * v10; 100a6: 9641a157 vmul.vv v2,v4,v3 100aa: 2a208157 vor.vv v2,v2,v1 v13 ^= v10 / v11; 100ae: 863020d7 vdiv.vv v1,v3,v0 100b2: 2e1200d7 vxor.vv v1,v1,v4 __asm__ volatile ("vsw.v %1, %0
" : "=A"(b[40]) : "v"(v10)); 100b6: 0207e1a7 vsw.v v3,(a5) ...

うまくいっているようです。良かった良かった。

[編集者: すずき]
[更新: 2020年 7月 23日 00:27]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

link 編集する

北極送り

GitHub が北極にコードを保存する取り組み(私のソースコードが北極送りに? "GitHub" アカウントに謎のラベルが付与されたとの報告が多数 - やじうまの杜 - 窓の杜)をしているそうです。面白いこと考えますよね。


GitHub Arctic Code Vault Contributor

気づいたら自分の GitHub アカウントにも Arctic Code Vault Contributor と出ていました。有名な OSS には関わってないし縁がないと思っていましたが、どうやら Linux にコントリビュートしていたので出てきたっぽいです。いわれてみると Linux も GitHub にミラーされてました。

未来人は現代人を理解できるだろうか?

現代人をもってしても 1000年前の文字の解読(例: ヒエログリフ、前 3200年〜4世紀、19世紀頃に解読された)はとても苦労したこと、解読されていない古代文字がまだまだあることを考えれば、現代文字や文明を遺しても未来人が理解不能で終わってしまう可能性もあるわけです。

少なくとも未来文明は現代文明より遥か上の水準に発展していないと、仮に現代文字や文明を発見できても、真に理解するのは難しいでしょう。

こんなことを考えると、実は Code Vault の取り組みは「地球の未来は今より進んでいるはず」という信頼や願望が前提になっていることが見て取れます。人類か、それ以外の生命体か、誰の手に渡るかわかりませんが、SF 的なロマンがありますよね。

[編集者: すずき]
[更新: 2020年 7月 23日 12:53]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

link 編集する

GCC を調べる - その 16 - 自動ベクトル化を有効にする

目次: GCC を調べる - まとめリンク

GCC には自動ベクトル化(tree-vectorize)機能があります。ループ処理を自動的に SIMD 命令に置き換えるために使われているようです。現状の GCC が可変長のベクトル長に対応しているかどうかはわかりません。未対応ならば可変長のベクトル長に対応する実装が必要になりますが、非常に難しそうです。

可変長のベクトルの扱いはひとまず横に置くとして、RISC-V のベクトルを「とても長い固定長の SIMD」とみなして自動ベクトル化を動かします。

自動ベクトル化を有効にするコード

// gcc/config/riscv/riscv.c

/* Implement TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES.  */

static unsigned int
riscv_autovectorize_vector_modes (vector_modes *modes, bool)
{
  if (TARGET_VECTOR)
    {
      modes->safe_push (V64SImode);
      modes->safe_push (V32SImode);
    }

  return 0;
}

...

#undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
#define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES riscv_autovectorize_vector_modes

自動ベクトル化を有効にする方法は簡単で、これだけです。

テスト用の int 配列をコピーする関数

void *cpy(void *dst, const void *src, int n)
{
	int *d = dst;
	const int *s = src;
	int i;

	for (i = 0; i < n / sizeof(*d); i++) {
		d[i] = s[i];
	}

	return dst;
}

この関数がベクトル化あり、なしでどのように変わるか見ます。

自動ベクトル化の結果

//★★自動ベクトル化、あり

                d[i] = s[i];
   100b8:       1202e007                vlw.v   v0,(t0)
   100bc:       10038393                addi    t2,t2,256
   100c0:       f0038793                addi    a5,t2,-256
   100c4:       10028293                addi    t0,t0,256
   100c8:       0207e027                vsw.v   v0,(a5)
        for (i = 0; i < n / sizeof(*d); i++) {
   100cc:       fee296e3                bne     t0,a4,100b8 <cpy+0x44>
   100d0:       00661293                slli    t0,a2,0x6
   100d4:       02568963                beq     a3,t0,10106 <cpy+0x92>
   100d8:       959a                    add     a1,a1,t1
   100da:       932a                    add     t1,t1,a0
                d[i] = s[i];
   100dc:       0005a383                lw      t2,0(a1)


//★★自動ベクトル化、なし

                d[i] = s[i];
   10080:       0005a303                lw      t1,0(a1)
        for (i = 0; i < n / sizeof(*d); i++) {
   10084:       0591                    addi    a1,a1,4
   10086:       0291                    addi    t0,t0,4
                d[i] = s[i];
   10088:       fe62ae23                sw      t1,-4(t0)
        for (i = 0; i < n / sizeof(*d); i++) {
   1008c:       fe759ae3                bne     a1,t2,10080 <cpy+0xc>
        }

        return dst;
}
   10090:       8082                    ret

ソースコードではベクトル型を使っていませんが、自動ベクトル化により 256バイト(= 64要素)ずつ処理され、vlw.v, vsw.v 命令が使われるようになったことがわかります。

[編集者: すずき]
[更新: 2020年 7月 16日 10:17]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

link 編集する

OpenCL と ICD

OpenCL は複数のベンダーのデバイスを同時に扱うことができます。ICD(Installable Client Driver)というそうです。ICD は GPU などのデバイスを制御し、アプリケーションと ICD の間に ICD ローダーが存在します。


アプリケーション、ICD ローダー、ICD の関係


Debian でのライブラリ名

Debian Testing では ICD ローダーとして ocl-icd-2.2.12 が使われています。

Debian Testing の ICD loader
$ apt-cache search ocl-icd-libopencl1

ocl-icd-libopencl1 - Generic OpenCL ICD Loader

ローダーのソースコードは GitHub(リンク)にあります。

先程、図示したもの以外にも ICD はいくつか実装があります。現時点の Debian Testing では下記が提供されていました。

  • pocl-opencl-icd: 主に CPU 向け
  • beignet-opencl-icd: 比較的古い Intel GPU 向け
  • intel-opencl-icd: 比較的新しい Intel GPU 向け、Testing にしか存在しない
  • mesa-opencl-icd: AMD GPU 向け
  • nvidia-opencl-icd: nVidia GPU 向け、ソースコードは公開されていない

Intel は ICD のソースコードを完全にオープンにしています。NVIDIA は公開していません。AMD もないのかな?

ICD のロード手順

動作を追ってみたいと思います。アプリケーションには clinfo を使います。ocl-icd は環境変数 OCL_ICD_DEBUG=15 に設定すると、動作時に詳細なログを出力します。デバッガで追うのと併用するとわかりやすいです。

  • clinfo: clGetPlatformIDs() を呼ぶ
  • ocl-icd: _initClIcd() -> _initClIcd_real() -> __initClIcd()
  • ocl-icd: _find_num_icds(): /etc/OpenCL/vendors の *.icd ファイルを見る(*.so へのパスが書いてある)
  • ocl-icd: _load_icd(): *.so を dlopen()
  • ocl-icd: _find_and_check_platforms(): 後述

ローダーが走査するディレクトリは /etc/OpenCL/vendors がハードコードされていますが、環境変数 OPENCL_VENDOR_PATH で変更できます。

ICD のロードの中心となる処理は _find_and_check_platforms() です。

  • dlsym() で clGetExtensionFunctionAddress() のアドレスを得る
  • clGetExtensionFunctionAddress() で clIcdGetPlatformIDsKHR() のアドレスを得る
  • clGetExtensionFunctionAddress() で clGetPlatformInfo() のアドレスを得る
  • clIcdGetPlatformIDsKHR() でプラットフォーム数とプラットフォームの情報を得る

プラットフォームは説明が難しいですが、OpenCL API の実体+任意のドライバ固有のデータとでも言いましょうか。変数の型は cl_platform_id * 型です。cl_platform_id は少なくとも先頭のメンバは struct _cl_icd_dispatch *dispatch でなければなりません。dispatch の後ろには他の情報が入っていても問題ないようです。

cl_platform_id と 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年 7月 15日 20:37]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
   2020年 7月 22日 -
      2020年 7月 13日  
link もっと後

管理用メニュー

link 記事を新規作成

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDF ファイル RSS 1.0
QR コード QR コード

最終更新: 8/8 14:57

カレンダー

<2020>
<<<07>>>
---1234
567891011
12131415161718
19202122232425
262728293031-

最近のコメント 5件

  • link 20年08月06日
    hdk 「言い訳がいいですね。実際にもし石膏ボード...」
    (更新:08/08 14:57)
  • link 20年07月28日
    すずき 「乗る用事はないし、乗ろうと思って、いつも...」
    (更新:07/30 22:19)
  • link 20年07月28日
    hdk 「さすがに月イチくらいは動かしてあげてくだ...」
    (更新:07/30 21:40)
  • link 20年06月28日
    すずき 「コメントありがとうございます。私もやって...」
    (更新:07/12 00:53)
  • link 20年06月28日
    匿名 「「階段抜き」「ノンエスカレーター」「効率...」
    (更新:07/11 18:26)

最近の記事 3件

link もっとみる
  • link 20年08月08日
    すずき 「[車検] 車検証と検査証票(フロントガラスに貼るステッカー)が届き...」
    (更新:08/08 14:35)
  • link 20年08月07日
    すずき 「[Wikipedia] Wikipedia に寄付しました。といっ...」
    (更新:08/08 14:24)
  • link 20年08月06日
    すずき 「[エアコンが落ちそうで怖い] Twitter で「これ便利」と紹介...」
    (更新:08/08 14:24)

こんてんつ

open/close wiki
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報