NEC FortranとSX-Aurora TSUBASAを使ってみた（その1）

# 概要
NECが開発，販売しているSX-Aurora TSUBASAを使う機会を得たので，nfort（NECが提供しているFortranコンパイラ）と共に使ってみました．

率直な感想は下記の通りでした．（詳細はいくつかの記事に分けて投稿します．）
- SX-Aurora TSUBASA簡単速い🚀
- 予想していたよりはコンパイラの対応状況はしっかりしている
- 予想通りモダンな機能を使ったコードはビルドに失敗することがある
- 想定されている領域である数値計算で使う分には問題なさそう

著者はベクトル型計算機を使った経験がないので，誤り等あればご指摘お願いします．

- [その1](https://qiita.com/implicit_none/items/8573afae2ac87532b7e9)
- [その2 - fpm, stdlibを使ってみた](https://qiita.com/implicit_none/items/abe5104e980ccc7d92b1)
- [その3 - stream ベンチマークやってみた](https://qiita.com/implicit_none/items/cebda1fbb26920326a41)
- [その4 - 姫野ベンチマークやってみた](https://qiita.com/implicit_none/items/ed280b88083d46044d1e)
- [その5 - ベクトル和](https://qiita.com/implicit_none/items/c0cf96b582bf62ba4d4e)

# SX-Aurora TSUBASAについて
NECは，半世紀にわたって[ベクトル型のスーパーコンピュータ](https://jpn.nec.com/hpc/sxauroratsubasa/history/index.html)を開発し，SXシリーズとして販売してきました．[東北大学](https://www.ss.cc.tohoku.ac.jp)は伝統的にSXシリーズを導入しているようですし，海洋研究開発機構の[地球シミュレータ](https://www.jamstec.go.jp/es/jp/)もNECが開発しています．SX-9がアニメーション映画サマーウォーズに登場して，話題になっていました．

SX-Aurora TSUBASAはSXシリーズの流れをくむモデルですが，これまでのSXシリーズが専用筐体をもつ大型計算機の形態で提供されてきたこととは異なり，PCI-Expressカードとして提供されています．計算リソースとして注目されているGPUと同じように，手軽に利用できるようにして，ユーザ数の増加＋GPUを使っている顧客の獲得を狙っているのではと考えています．

SX-Aurora TSUBASAにはベクトルプロセッサが搭載されており，これをベクトルエンジン（VE）と呼んでいます．また，SX-Aurora TSUBASAが接続されている計算機を，ベクトルホスト（VH）と呼びます．NVIDIA CUDAでは，GPUをデバイス，GPUが接続されている計算機をホストと呼びます．それと同じと考えて問題無いでしょう．

以降は，SX-Aurora TSUBASAをSXATと省略します．
著者が利用したSXATは，Vector Engine Type 10Cです．PCI-Expressカードの名称なのか，搭載されているチップのモデル番号なのかがよくわかっていません．恐らくですが，チップのモデル番号がType 10Cで，それを搭載しているPCI-ExpressカードがVector Engine Type 10Cだと判断しています．Vector Engine Type 10Cは，タワー型のワークステーションに搭載するためのアクティブ空冷型です[^nec_pcccw2018]．

[^nec_pcccw2018]: https://www.pccluster.org/ja/event/2018/02/180215_pccWS_hagiwara.pdf

カードには，8コアのVEと24GBのHBM2メモリが搭載されています．コアの動作周波数は1.4GHz，1コアあたりの性能は268.8 GFLOPSです．チップとしての性能は2.15 TFLOPS，VE-メモリ間のバンド幅は0.75 TB/sです[^nec_catalog]．NVIDIAのTesla V100と比較すると下記表のようになります．

[^nec_catalog]: https://jpn.nec.com/hpc/sxauroratsubasa/pdf/sxauroratsubasa.pdf

||VE Type 10C|Tesla V100|
|:--|:--|:--|
|単精度演算性能|2.15 TFLOPS|14 TFLOPS|
|メモリ|24 GB|32 GB|
|バンド幅|0.75 TB/s|0.9 TB/s|

演算性能は少し見劣りしますが，バンド幅は遜色ありません．Type 10Cよりも上位のモデルでは，メモリが48 GB，バンド幅は倍の1.53 TB/sまで上がるようなので，SXATはメモリ性能が非常に高いことが判ります．演算よりもメモリ律速の処理では，GPUを使うよりも性能の向上が期待できるでしょう．

プログラム実行のモデルは3種類あります[^nec_pcccw2021]．
- プログラムを実行すると最初から最後までVE上でプログラムが実行されるTransparent実行
- 一部の処理だけをVEで実行するVE Offloading
- 一部の処理だけをベクトルホストで実行するVH Call

[^nec_pcccw2021]: https://www.pccluster.org/ja/event/data/pcccWS_220120_6_nec_masaoka.pdf

# Fortranコンパイラ
前置きが終わったので，ようやくFortranの話に入ります．

今回使用できたSXATが接続されている計算機には，NECのSDKがインストールされています．Fortranのコンパイラは2種類利用でき，nfortを使うとTransparent実行されるプログラムがビルドされます．VE OffloadingやVH Callのやり方がよくわからなかったのですが，もう一つのコンパイラであるmpinfortを使うことで実現できるのではないかと思います．本記事では，nfortのみ取り上げます．

## NEC Fortranコンパイラ
利用したnfortのバージョンは3.5.1です．
```console
$ nfort --version
nfort (NFORT) 3.5.1 (Build 16:22:03 Aug  2 2022)
Copyright (C) 2018,2022 NEC Corporation.
```

対応しているFortran標準はFortran 2008です．コンパイル時にオプション`-std=2008`を付与すると，規格への適合性をチェックしてくれます．

著者が過去に書いた記事内のコードを色々とビルドしてみましたが，概ねビルドできました．`do concurrent`も使用可能です．coarrayは使えるようですが，マニュアルによると並列実行はできないようです．判っているなと感じたのは`cpu_time`が1スレッドのCPU時間を取得するのか，全スレッドのCPU時間を取得するのかを環境変数で選択できるようになっていることです．主なターゲットが数値計算であり，スレッド並列をすることも多いことから，このような仕様になっていると思われます．

一方で，[自己参照の派生型（動的割付成分をもつ再帰型）](https://qiita.com/implicit_none/items/12c5404a11e6c237d100#%E5%8B%95%E7%9A%84%E5%89%B2%E4%BB%98%E6%88%90%E5%88%86%E3%82%92%E6%8C%81%E3%81%A4%E5%86%8D%E5%B8%B0%E5%9E%8B)はビルドに失敗します．

```Fortran:main.f90
program main
    use,intrinsic :: iso_fortran_env
    implicit none

    type :: person
        character      :: initial
        character(4)  :: name
        integer(int32) :: age
        integer(int32) :: birthyyyy
        integer(int32) :: birthmm
        integer(int32) :: birthdd
        character(3)   :: birthMonth
        type(person),allocatable :: ptrToPerson(:) ! Allocatable components of recursive type
    end type person

    type(person):: a_classroom(3)

    a_classroom(1) = person("A", "Adam", 20, 1998, 12, 4, "Dec")
    a_classroom(2) = person("N", "Nick", 21, 1997, 11, 4, "Nov")
    a_classroom(3) = person("Z", "Zack", 22, 1996, 10, 4, "Oct")

end program main
```

```console
$ nfort -std=f2008 -O0 main.f90 
nfort: /opt/nec/ve/nfort/3.5.1/libexec/fcom is abnormally terminated by SIGSEGV
```

おや？と思った挙動もあります．

### 変数名の制約
変数名に`unix`を用いてプリプロセスを有効にすると，ビルドに失敗します．

```Fortran:main.f90
program main
    implicit none

    logical :: unix

end program main
```

```console
$ nfort -fpp main.f90 
Error: main.f90, line 4: Syntax error
       detected at ::@1
[NEC Fortran Compiler pass 1 error termination, 1 error]
```

`unix`がプリプロセッサ識別子として定義されているのでしょうか？`unix`なんて変数名使わないだろうといえばそうなのですが，規格で使用が禁止されているわけでもないのに使えなくなるのは，いかがなものかと思います．（追記：これもfppの仕業のようです．）

### `include`ディレクティブ
NEC Fortranの`#include`ディレクティブを用いると，読み込まれるファイルの最終行にある継続行が自動的に削除されます．（行の継続記号が行頭にも付けられるのも奇妙ですが，これは致命的な問題にはなりません）

```Fortran:main.f90
program main
    implicit none
#include "print.inc"
    "greeting"
end program main
```

```Fortran:print.inc
print &
*, &
```

```console
gfortran -cpp -E inc.f90
# 1 "inc.f90"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "inc.f90"
program main
    implicit none

# 1 "print.inc" 1
print &
*, &
# 4 "inc.f90" 2
    "greeting"
end program main
```

```console
nfort -fpp -E main.f90
# 1 "main.f90"
program main
    implicit none
# 1 "./print.inc" 1 
print &
# 2
&*, 
# 4 "main.f90" 2 
    "greeting"
end program main
```

`include`文のような用途を想定し，文の途中に何かを展開するという用途は想定されていないようです．そのため，仮引数を`include`ディレクティブで指定している[json-fortran](https://github.com/jacobwilliams/json-fortran)は，そのままではビルドできません．

`#include`ディレクティブの挙動として，指定したファイルがそのまま展開されることを期待している人が大半でしょう．ところが，gfortran，Intel Fortranは指定したファイルがそのまま展開される一方で，NAG Fortranは，NEC Fortranと同じく読み込まれるファイルの最終行にある継続行が自動的に削除されます．NAG Fortranに関してはfppのドキュメントが見つけられたものの，この件に関する記述はありませんでした．Fortran Preprocessorは標準で規定されていない（はず）ので，どの挙動が正しいかは断言できません．使う側で気をつけるしかないのでしょう．

### `push_macro`, `pop_macro`
`push_macro`, `pop_macro`はサポートされていないので，`error: unknown fpp directive.`というエラーが発生します．

# まとめ
NEC Fortran Compilerを使う機会を得たので，少し触ってみた感想をまとめました．半分ほどSX-Aurora TSUBASAの紹介みたいになってしまいましたが，実際に使ってみた内容を続けて投稿していきます．