イントロダクション
半精度浮動小数点数について
IEEE754 で半精度浮動小数点数 Half-precision floating-point format(以下 float16 と表記します)として 16bit の浮動小数点数が定義されています。主に機械学習やコンピュータグラフィックスにおいて、GPU との通信やメモリのコスト削減を目的に用いられています。
JavaScript における扱い
WebGL では "OES_texture_half_float"
, "OES_texture_half_float_linear"
, "EXT_color_buffer_half_float"
の拡張を用いることで float16 を扱うことができます。また WebGL 2.0 ではデフォルトで扱えます。
しかし残念なことに現状 JavaScript では float16 を扱える TypedArray
や DataView
のメソッドは存在しません。つまり Fetch API などで直接バイナリを取得し、そのまま WebGL に渡すといったことは出来ますが、float16 の値を JavaScript で動的に変更したいときに number
(64bit float)型との変換を自前で用意しなければなりません。
パッケージの紹介
というわけで float16 を扱えるパッケージを公開しました。
使い方
README.md を読んでいただけるとわかると思いますが、Float16Array
の他にも getFloat16
, setFloat16
, hfround
が用意されています。基本的に ECMAScript の TypedArray
, DataView
, Math.fround
と同じように使えると思います。
Float16Array
の実装を見てもらえるとわかると思いますが、Proxy
でラップされています。よって IE 11 では動きません。また WebGL にバイナリを渡す時に ArrayBuffer
や Uint16Array
として渡す必要があります。
例えば "OES_texture_half_float"
を用いて Float16Array
のバッファを渡したい場合、以下のように Uint16Array
でラップしなければなりません。
const ext = gl.getExtension("OES_texture_half_float");
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, ext.HALF_FLOAT_OES, new Uint16Array(image.buffer));
Stage 1
喜ばしいことに ES Discuss の該当のトピックにこのパッケージの周知を図ったところ、TC39 May 23, 2017 Meeting にて取り上げていただき、Stage 1 入りを果たしました。
今後の展望としてはこのミーティングで挙げられた問題点や疑問点の解消、float16 が本当に JavaScript に必要なのかといった点で議論がなされると思いますので、もしよろしければフィードバックをいただければ幸いです。
参考
実装に用いたアルゴリズム