🔬

Stage 1 Float16Array (with ponyfill)

2 min read

イントロダクション

半精度浮動小数点数について

IEEE754 で半精度浮動小数点数 Half-precision floating-point format(以下 float16 と表記します)として 16bit の浮動小数点数が定義されています。主に機械学習やコンピュータグラフィックスにおいて、GPU との通信やメモリのコスト削減を目的に用いられています。

https://ja.wikipedia.org/wiki/半精度浮動小数点数

JavaScript における扱い

WebGL では "OES_texture_half_float", "OES_texture_half_float_linear", "EXT_color_buffer_half_float" の拡張を用いることで float16 を扱うことができます。また WebGL 2.0 ではデフォルトで扱えます。

しかし残念なことに現状 JavaScript では float16 を扱える TypedArrayDataView のメソッドは存在しません。つまり Fetch API などで直接バイナリを取得し、そのまま WebGL に渡すといったことは出来ますが、float16 の値を JavaScript で動的に変更したいときに number(64bit float)型との変換を自前で用意しなければなりません。

パッケージの紹介

というわけで float16 を扱えるパッケージを公開しました。

https://github.com/petamoriken/float16/

使い方

README.md を読んでいただけるとわかると思いますが、Float16Array の他にも getFloat16, setFloat16, hfround が用意されています。基本的に ECMAScript の TypedArray, DataView, Math.fround と同じように使えると思います。

Float16Array の実装を見てもらえるとわかると思いますが、Proxy でラップされています。よって IE 11 では動きません。また WebGL にバイナリを渡す時に ArrayBufferUint16Array として渡す必要があります。

例えば "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));

https://developer.mozilla.org/en-US/docs/Web/API/OES_texture_half_float

Stage 1

喜ばしいことに ES Discuss の該当のトピックにこのパッケージの周知を図ったところ、TC39 May 23, 2017 Meeting にて取り上げていただき、Stage 1 入りを果たしました。

https://esdiscuss.org/topic/float16array#content-16

https://github.com/tc39/notes/blob/master/meetings/2017-05/may-23.md#16ig-float16-on-typedarrays-dataview-mathhfround-for-stage-1

今後の展望としてはこのミーティングで挙げられた問題点や疑問点の解消、float16 が本当に JavaScript に必要なのかといった点で議論がなされると思いますので、もしよろしければフィードバックをいただければ幸いです。

参考

実装に用いたアルゴリズム

http://fox-toolkit.org/ftp/fasthalffloatconversion.pdf

Discussion

ログインするとコメントできます