BFloat16の適用と実装状況

# はじめに
bfloat16は、いろいろソフトが出てきているので、まとめてみる。
## Bfloat16の適用範囲について
[Bfloat16では、学習ができるとの現象論的論文が出ている。](https://arxiv.org/abs/1905.12322)すでに、ResNet以外にGAN等複雑な計算を行って、そん色ない結果を出している。
また、[Ising modelのモンテカルロでもFP32と比べてそん色ない結果](https://arxiv.org/abs/1903.11714)が出ている。

# 使い方
## TensorFlow
[`tf.cast`](https://www.tensorflow.org/api_docs/python/tf/cast)コードの例がある。

## PyTorch
TPUを使った場合、bfloat16を使える。[サンプルコードもある。](https://github.com/pytorch/xla/blob/master/test/test_operations.py#L1332-L1340)

## AWS inf1
[コンパイラで、FP32からBF16に自動変換する](https://github.com/aws/aws-neuron-sdk/blob/master/docs/neuron-cc/readme.md)。推論だけだから？

# フレームワーク等での対処
## 深層学習ソフトでの数値変換
FP32からBFloat16に変換する際、丸め誤差およびNaNに対する処理が必要との知見が、Googleがメインに開発している[TensorFlowの実装が出ておりそこで説明されている。](https://github.com/tensorflow/tensorflow/blob/v2.1.0/tensorflow/core/lib/bfloat16/bfloat16.h#L178-L355)もともとは、[こちらの記事](https://qiita.com/syoyo/items/506583df6d79dedaf5fb)にあったが、ちょっと整理してみた。
まず、NaNの値は、例外を発生しないquiet NaNに変更している。
次に、丸め誤差は、若干複雑なので、表にして示す。

<table>
<tr>
  <th>符号</th>
  <th colspan=8>指数(8ビット)</th>
  <th colspan=23>仮数(23ビット)</th>
</tr>
<tr>
  <td>S</td>
  <td>E</td>
  <td>E</td>
  <td>E</td>
  <td>E</td>
  <td>E</td>
  <td>E</td>
  <td>E</td>
  <td>E</td>
  <td>F</td>
  <td>F</td>
  <td>F</td>
  <td>F</td>
  <td>F</td>
  <td>F</td>
  <td>L</td>
  <td>R</td>
  <td>T</td>
  <td>T</td>
  <td>T</td>
  <td>T</td>
  <td>T</td>
  <td>T</td>
  <td>T</td>
  <td>T</td>
  <td>T</td>
  <td>T</td>
  <td>T</td>
  <td>T</td>
  <td>T</td>
  <td>T</td>
  <td>T</td>
</tr>
</table>

ここで、FとLの7ビットは、bfloat16の仮数である。そして、Lは最下位のビットである。次に、Rは、丸めるビットである。Tは、それ以下のビットである。ここで、RとTのビットの値によって、Lのビットの繰上か繰下を決める。

|L|R|T|繰上繰下|
|:--:|:--:|:--:|:--:|
|0|0|-|繰下|
|1|0|-|繰下|
|0|1|全て0|繰下|
|1|1|-|繰上|
|0|1|1がある|繰上|



## ソフトの実装状況
ツールは、未成熟であり2020年1月現在サポートされつつあるといった感じである。以下にサポートされているソフトを示す。

# 参考文献
## 一般
### 使えている例
- [A Study of BFLOAT16 for Deep Learning Training(2019/05)](https://arxiv.org/abs/1905.12322)
- [Leveraging the bfloat16 Artificial Intelligence Datatype For Higher-Precision Computations(2019/04)](https://arxiv.org/abs/1904.06376)
- [(ACM SC19)High Performance Monte Carlo Simulation of Ising Model on TPU Clusters(2019/03)](https://arxiv.org/abs/1903.11714)
   - [実際のコード](https://github.com/google-research/google-research/tree/master/simulation_research/ising_model)

## ソフト側対応
### 一般
- [float32 -> bfloat16 変換では NaN と丸めを考慮すると完璧](https://qiita.com/syoyo/items/506583df6d79dedaf5fb)

### 深層学習フレームワーク
- [(TensorFlow) Converts a float point to bfloat16, with round-nearest-to-even as rounding method.](https://github.com/tensorflow/tensorflow/blob/v2.1.0/tensorflow/core/lib/bfloat16/bfloat16.h#L178)
    - [[XLA][BF16] Add bf16 rounding function.](https://github.com/tensorflow/tensorflow/commit/4c56dcaade7cee9f75740e2f03e30bdf3a6f93be)
        - 2018年3月に丸めの処理が追加されている。
- [(PyTorch)Enable log_softmax and CrossEntropyLoss for bfloat16 (#24457)](https://github.com/pytorch/pytorch/commit/378881e903999342c84ad6f20224f712148e0359)
   - PyTorch 1.3.0からbfloat16によるクロスエントロピー対応が入った。その際丸めも考慮した。コード自体は、2019年4月だが、マージは2019年9月
- [(tvm)incubator-tvm/3rdparty/bfloat16/bfloat16.cc](https://github.com/apache/incubator-tvm/blob/master/3rdparty/bfloat16/bfloat16.cc) TensorFlowのbfloat16.ccが取り込まれている

### 数値演算ライブラリ
- [(Intel oneDNN)Bfloat16 Training](https://intel.github.io/mkl-dnn/dev_guide_training_bf16.html)
- [pytorch/FBGEMM](https://github.com/pytorch/FBGEMM) FP32/BF16変換のパッチ等が取り込まれつつある。

### ツール
- [Clang 9.0](https://github.com/llvm-mirror/clang/commit/7bdbc78bb83e99cfc4bc1f9cfd9fa128cb850771#diff-3bc54efb746652488897d103f24820b7)(2019/09) [LLVM 9.0](https://github.com/llvm-mirror/llvm/commit/0e258a059f068bee0445c6186ef40beceffbb64d)(2019/09)
  - GCC10からBFLOAT16はサポート(2020年5月ごろ？)
- [(binutils)Add assembler and disassembler support Intel AVX512 BF16:](https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commitdiff;h=d6aab7a11b8bd85de43f9fe6b1cea95b504e73ad)
   - [x86: Support Intel AVX512 BF16](https://github.com/bminor/binutils-gdb/commit/d6aab7a11b8bd85de43f9fe6b1cea95b504e73ad) binutils 2.33.1(2019/10)より
- [QEMU version 4.2.0 released(2019/12)](https://www.qemu.org/2019/12/13/qemu-4-2-0/)
- [(Julia)JuliaComputing/BFloat16s.jl](https://github.com/JuliaComputing/BFloat16s.jl/blob/master/src/bfloat16.jl)


## CPU/GPU
### Amazon(GPU)(提供済)
- [Amazon EC2 Update – Inf1 Instances with AWS Inferentia Chips for High Performance Cost-Effective Inferencing](https://aws.amazon.com/blogs/aws/amazon-ec2-update-inf1-instances-with-aws-inferentia-chips-for-high-performance-cost-effective-inferencing/)

### AMD(GPU)
- [MIOpen: An Open Source Library For Deep Learning Primitives](https://arxiv.org/abs/1910.00078)

### ARM(CPU)
- [Bfloat16 Processing for Neural Networks(IEEE Xplore: 21 October 2019)](https://ieeexplore.ieee.org/document/8877390)
- [BFloat16 processing for Neural Networks on Armv8-A(blog)](https://community.arm.com/developer/ip-products/processors/b/ml-ip-blog/posts/bfloat16-processing-for-neural-networks-on-armv8_2d00_a)

### Google(TPUv2/v3)(提供済み)
- [BFloat16: The secret to high performance on Cloud TPUs](https://cloud.google.com/blog/products/ai-machine-learning/bfloat16-the-secret-to-high-performance-on-cloud-tpus)
- [Livestream Day 1: Stage 8 (Google I/O '18)](https://www.youtube.com/watch?v=vm67WcLzfvc&t=2555)
- [(NIPS18)Image Classification at Supercomputer Scale(2018/11)](https://arxiv.org/abs/1811.06992) 畳み込み演算はbfloat16を使っている。
- 以下の時点ではBFloat16は、出ていない。評価中だったと思われる。
   - [(NIPS17)Machine Learning for Systems and Systems for Machine Learning Jeff Dean Google Brain team](http://learningsys.org/nips17/assets/slides/dean-nips17.pdf)

### Intel(CPU/GPU)
- [bfloat16 - Hardware Numerics Definition](https://software.intel.com/en-us/download/bfloat16-hardware-numerics-definition)
- [Lower Numerical Precision Deep Learning Inference and Training](https://software.intel.com/en-us/articles/lower-numerical-precision-deep-learning-inference-and-training)
- GPU側は、[Intel oneDNNのコードで見かける。](https://github.com/intel/mkl-dnn/commit/47903f80610c14e2deca82eb1bbe415646cd5805)

### NVIDIA(GPU)
- [Enabled bfloat16 for cuda #27259](https://github.com/pytorch/pytorch/pull/27259) パッチ自体はFacebookが出したもの

## その他
- [特殊値](https://www.xlsoft.com/jp/products/intel/compilers/fcw/12/ug/fpops/fortran/fpops_special_value_f.htm) IEEE 754が引用できないので仮に引用
- [(SIAM)Low Precision Floating-Point Formats: The Wild West of Computer Arithmetic(2019/11)](https://sinews.siam.org/Details-Page/low-precision-floating-point-formats-the-wild-west-of-computer-arithmetic)