Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 189 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,189 @@
# rccs-pytorch
# rccs-pytorch

## はじめに

本書では、「富岳」におけるAIフレームワークPyTorch v2.9系のビルド手順および標準的なテストデータ(mnist)を用いた動作確認の手順について述べる。

## AIプレームワークPyTorchのバージョンアップ

### PyTorchおよび主要モジュールの版数

ビルド対象であるPyTorchおよび主要モジュールの版数を示す。本作業では、Python v3.10、PyTorch v2.9.1、Numpy v1.22.4、Scipy v1.10.1、OneDNN v3.7.1、Horovod v0.26.1を採用することとした。

| モジュール名 | 版数 |
| --- | --- |
| Python | v3.10 |
| PyTorch | v2.9.1 |
| Numpy | v1.22.4 |
| Scipy | v1.10.3 |
| oneDNN | v3.7.1 |
|Horovod | v0.26.1 |

### ビルド環境の整備

Pytorch v2.9.1の「富岳」向けビルドでは、富士通Githubで公開されている” 富士通 Supercomputer PRIMEHPC FX1000/FX700 上の PyTorch 構築手順”から入手可能なPytorch v1.13.1向けのビルド用スクリプトを利用する。言語環境としては、「富岳」にインストールされているllvm-v21.1.0を用いた。なお、現行の富士通製コンパイラはPytorch v2.9.1をビルドするために必要なC++言語規格要件を満たさない。

#### (1) 富士通GithubからPyTorchをクローンする。

```
$ git clone https://github.com/fujitsu/pytorch.git
```

#### (2) pytorch/ディレクトリへ移動し、公式PyTorchのリポジトリを認識する。

```
$ PYTORCH_TOP=$(cd $(dirname ${BASH_SOURCE:-$0})/pytorch && pwd)
$ PATCH_DIR=$(cd $(dirname ${BASH_SOURCE:-$0})/patch && pwd
$ cd ${PYTORCH_TOP}
$ git remote add upstream https://github.com/pytorch/pytorch.git
$ git fetch upstream v2.9.1
```

#### (3) 公式v2.3.1をベースに新しいブランチを作成する。

```
$ git checkout -b r2.9.1_for_a64fx FETCH_HEAD
```

#### (4) 富士通PyTorch v1.13.1から、ビルド用スクリプト一式を取り込む。

```
$ git cherry-pick 17afed104f0a2ac47bab78aebf584fb3c578e707
$ git reset --mixed HEAD^
$ git add scripts/fujitsu --all
$ git commit -m "add scripts/fujitsu"
```

#### (5) pytorchに対するパッチを適用し、numpyおよびtensorpipeに対するパッチを所定のディレクトリに置く。
```
$ cd ${PYTORCH_TOP} && patch -p 1 < ${PATCH_DIR}/pytorch.patch
$ cp ${PATCH_DIR}/numpy.patch ${PYTORCH_TOP}/scripts/fujitsu
$ cp ${PATCH_DIR}/tensorpipe.patch ${PYTORCH_TOP}/scripts/fujitsu
```


### ビルド手順
ビルド環境の整備後、計算ノード上にて以下のように実行する。なお、すべてのscriptを実行するのには15時間程度を要する。
```
$ cd ${PYTORCH_TOP}/pytorch/scripts/fujitsu
$ . ./env.src
$ bash 1_python.sh
$ bash 3_venv.sh
$ bash 4_numpy_scipy.sh
$ bash 5_pytorch.sh
$ bash 6_vision.sh
$ bash 7_horovod.sh
$ bash 8_libtcmalloc.sh
```

ビルド用のスクリプトの実行後に出力されるpip3 list(pip3_list.txt)の内容を示す。
```
Package Version
------------------ ------------------
beniget 0.4.2.post1
build 1.4.0
certifi 2026.1.4
cffi 2.0.0
charset-normalizer 3.4.4
cloudpickle 3.1.2
cmake 4.2.1
Cython 0.29.37
exceptiongroup 1.3.1
expecttest 0.3.0
filelock 3.20.3
fsspec 2026.1.0
gast 0.6.0
horovod 0.26.1
hypothesis 6.151.4
idna 3.11
iniconfig 2.3.0
Jinja2 3.1.6
lintrunner 0.13.0
MarkupSafe 3.0.3
mpmath 1.3.0
networkx 3.4.2
ninja 1.13.0
numpy 1.22.4
optree 0.18.0
packaging 26.0
Pillow 8.4.0
pip 25.3
pluggy 1.6.0
ply 3.11
psutil 7.2.2
pybind11 3.0.1
pycparser 3.0
Pygments 2.19.2
pyproject_hooks 1.2.0
pytest 9.0.2
pythran 0.18.1
PyYAML 6.0.3
requests 2.32.5
SciPy 1.10.1
setuptools 73.0.1
six 1.17.0
sortedcontainers 2.4.0
sympy 1.14.0
tomli 2.4.0
torch 2.9.1a0+gitcdd1b45
torchvision 0.24.1+d801a34
typing_extensions 4.15.0
urllib3 2.6.3
uv 0.9.28
wheel 0.46.3
```

### 標準的なテストデータ(mnist)を用いた動作確認

ビルドしたPyTorch v2.9.1の動作確認では、機械学習の画像認識の学習においてサンプルデータ
としてよく利用される「mnist」を用いた。
mnistを実行するコードは公式PyTorchのgithubのexamplesから入手した。
(https://github.com/pytorch/examples/blob/main/mnist/main.py)
また、mnistのコードを実行するスクリプトにはscripts/fujitsu/run1proc.shを流用した。

#### mnistの実行環境の構築

run/ディレクトリに格納されている以下の2つのファイルをscripts/fujitsu/配下にコピーする。
- mnist.py
- run1proc_mnist.sh

#### mnistの実行
mnistをジョブ実行する。
```
$ cd ${PYTORCH_TOP}/pytorch/scripts/Fujitsu
$ pjsub ./run1proc_mnist.sh
```

以下の出力によりmnistがPyTorch v2.9.1で正常に動作していることを確認した。

```
Train Epoch: 1 [0/60000 (0%)] Loss: 2.329474
Train Epoch: 1 [640/60000 (1%)] Loss: 1.425025
Train Epoch: 1 [1280/60000 (2%)] Loss: 0.797880
Train Epoch: 1 [1920/60000 (3%)] Loss: 0.536055
Train Epoch: 1 [2560/60000 (4%)] Loss: 0.444745
Train Epoch: 1 [3200/60000 (5%)] Loss: 0.262757
:
Train Epoch: 1 [56960/60000 (95%)] Loss: 0.050381
Train Epoch: 1 [57600/60000 (96%)] Loss: 0.137881
Train Epoch: 1 [58240/60000 (97%)] Loss: 0.006410
Train Epoch: 1 [58880/60000 (98%)] Loss: 0.003386
Train Epoch: 1 [59520/60000 (99%)] Loss: 0.002083

Test set: Average loss: 0.0497, Accuracy: 9830/10000 (98%)

Train Epoch: 2 [0/60000 (0%)] Loss: 0.026067
Train Epoch: 2 [640/60000 (1%)] Loss: 0.045588
Train Epoch: 2 [1280/60000 (2%)] Loss: 0.069181
Train Epoch: 2 [1920/60000 (3%)] Loss: 0.178524
Train Epoch: 2 [2560/60000 (4%)] Loss: 0.084490
Train Epoch: 2 [3200/60000 (5%)] Loss: 0.047848
:
Train Epoch: 2 [56960/60000 (95%)] Loss: 0.038513
Train Epoch: 2 [57600/60000 (96%)] Loss: 0.112719
Train Epoch: 2 [58240/60000 (97%)] Loss: 0.022632
Train Epoch: 2 [58880/60000 (98%)] Loss: 0.009396
Train Epoch: 2 [59520/60000 (99%)] Loss: 0.002736

Test set: Average loss: 0.0375, Accuracy: 9877/10000 (99%)
```
102 changes: 102 additions & 0 deletions llvm19.1.4/patch/numpy.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
diff --git a/numpy/distutils/fcompiler/__init__.py b/numpy/distutils/fcompiler/__init__.py
index d8dcfa8..ebe0647 100644
--- a/numpy/distutils/fcompiler/__init__.py
+++ b/numpy/distutils/fcompiler/__init__.py
@@ -745,7 +745,7 @@ def wrap_unlinkable_objects(self, objects, output_dir, extra_dll_dir):
('cygwin.*', ('gnu', 'intelv', 'absoft', 'compaqv', 'intelev', 'gnu95', 'g95')),
('linux.*', ('arm', 'gnu95', 'intel', 'lahey', 'pg', 'nv', 'absoft', 'nag',
'vast', 'compaq', 'intele', 'intelem', 'gnu', 'g95',
- 'pathf95', 'nagfor', 'fujitsu')),
+ 'pathf95', 'nagfor', 'fujitsu', 'llvm')),
('darwin.*', ('gnu95', 'nag', 'nagfor', 'absoft', 'ibm', 'intel', 'gnu',
'g95', 'pg')),
('sunos.*', ('sun', 'gnu', 'gnu95', 'g95')),
diff --git a/numpy/distutils/fcompiler/llvm.py b/numpy/distutils/fcompiler/llvm.py
new file mode 100644
index 0000000..f3db492
--- /dev/null
+++ b/numpy/distutils/fcompiler/llvm.py
@@ -0,0 +1,71 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+
+from numpy.distutils.fcompiler import FCompiler, dummy_fortran_file
+from sys import platform
+from os.path import join, dirname, normpath
+
+compilers = ['LlvmFlangFCompiler']
+
+import functools
+
+class LlvmFlangFCompiler(FCompiler):
+ compiler_type = 'llvm'
+ description = 'LLVM Fortran Compiler'
+ version_pattern = r'\s*flang.*version (?P<version>[\d.-]+).*'
+
+ possible_executables = ['flang']
+
+ executables = {
+ 'version_cmd': ["", "--version"],
+ 'compiler_f77': ["flang", "-fPIC"],
+ 'compiler_fix': ["flang", "-fPIC", "-ffixed-form"],
+ 'compiler_f90': ["flang", "-fPIC"],
+ 'linker_so': ["flang", "-fPIC", "-shared"],
+ 'archiver': ["ar", "-cr"],
+ 'ranlib': None
+ }
+
+ pic_flags = ["-fPIC", "-DPIC"]
+ c_compiler = 'clang'
+ module_dir_switch = '-module ' # Don't remove ending space!
+
+ def get_libraries(self):
+ opt = FCompiler.get_libraries(self)
+ return opt
+
+ @functools.lru_cache(maxsize=128)
+ def get_library_dirs(self):
+ """List of compiler library directories."""
+ opt = FCompiler.get_library_dirs(self)
+ flang_dir = dirname(self.executables['compiler_f77'][0])
+ opt.append(normpath(join(flang_dir, '..', 'lib')))
+
+ return opt
+
+ def get_flags(self):
+ return []
+
+ def get_flags_free(self):
+ return []
+
+ def get_flags_debug(self):
+ return ['-g']
+
+ def get_flags_opt(self):
+ return ['-O3']
+
+ def get_flags_arch(self):
+ return []
+
+ def runtime_library_dir_option(self, dir):
+ return '-Wl,-rpath=%s' % dir
+
+
+if __name__ == '__main__':
+ from distutils import log
+ log.set_verbosity(2)
+ from numpy.distutils import customized_fcompiler
+ print(customized_fcompiler(compiler='llvm').get_version())
+
diff --git a/numpy/tests/test_public_api.py b/numpy/tests/test_public_api.py
index bb15e10..9369424 100644
--- a/numpy/tests/test_public_api.py
+++ b/numpy/tests/test_public_api.py
@@ -233,6 +233,7 @@ def test_NPY_NO_EXPORT():
"distutils.fcompiler.sun",
"distutils.fcompiler.vast",
"distutils.fcompiler.fujitsu",
+ "distutils.fcompiler.llvm",
"distutils.from_template",
"distutils.intelccompiler",
"distutils.lib2def",
Loading