PyTorch で "import torch" の際に Segmentation fault が起こる場合の対処方法

# はじめに

下記の記事で紹介されているチュートリアルをやってみたときに、私の環境では PyTorch が動かなくて上手くいきませんでした。

* [「AIエッジコンテスト(実装コンテスト)のチュートリアル【3: Ultra96ボードのCPUで推論実行】」@Qiita](https://qiita.com/HirokiNakahara/items/20742dc7d2a5be209b23)

# 症状

Python のプログラムに "import torch" があると、そこで Segmentation fault が発生します。

```console
shell$ python3
Python 3.6.9 (default, Nov  7 2019, 10:44:02)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import torch
Segmentation fault
```

# 環境

* Hardware: Ultra96-V2
* Processor: aarch64
* OS : Linux Kernel 4.19.0 (https://github.com/ikwzm/ZynqMP-FPGA-Linux)
* Root: Ubuntu 18.04 (https://github.com/ikwzm/ZynqMP-FPGA-Ubuntu18.04-Ultra96)
* Python: 3.6.9
* torch: 1.4.0a0+4bcf479


# 原因

私の環境での原因は libnuma1 がインストールされていないことでした。libnuma1 は色々なところで(例えば opencv 等)使われているので知らない間にインストールされていることが多いでしょう。たまたま私は、ほとんど素の状態の Ubuntu にインストールしたのでこの地雷を踏んでしまいました。

# 対策

apt で libnuma1 パッケージをインストールします。

```console
shell$ sudo apt install libnuma1
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  libnuma1
0 upgraded, 1 newly installed, 0 to remove and 22 not upgraded.
Need to get 19.4 kB of archives.
After this operation, 74.8 kB of additional disk space will be used.
Get:1 http://ports.ubuntu.com/ubuntu-ports bionic-updates/main arm64 libnuma1 a\
rm64 2.0.11-2.1ubuntu0.1 [19.4 kB]
Fetched 19.4 kB in 1s (16.0 kB/s)
Selecting previously unselected package libnuma1:arm64.
(Reading database ... 93315 files and directories currently installed.)
Preparing to unpack .../libnuma1_2.0.11-2.1ubuntu0.1_arm64.deb ...
Processing triggers for libc-bin (2.27-3ubuntu1) ...
```

これで import torch が正常に終了すれば成功です。

```console
shell$ python3
Python 3.6.9 (default, Nov  7 2019, 10:44:02)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import torch
>>>
```

# 参考

この問題を Google で import torch segmentation fault で検索すると次の記事がみつかりした。

* https://github.com/pytorch/pytorch/issues/4101
* https://github.com/pytorch/pytorch/issues/4111

やはり、私以外にも地雷を踏んだ人がいらっしゃるようです。
この issue のやりとりの中に Segmentation fault が起きるところを gdb でバックトレースした結果が載っていました。

```console
gdb python3
(gdb) r
...
>>> import torch
[New Thread 0x7ffff342e700 (LWP 11736)]
[New Thread 0x7ffff0c2d700 (LWP 11737)]
[New Thread 0x7fffee42c700 (LWP 11738)]
Thread 1 "python3" received signal SIGSEGV, Segmentation fault.
0x0000000000002260 in ?? ()

(gdb) bt
#0 0x0000000000002260 in ?? ()
#1 0x00007ffff7de76ba in call_init (l=<optimized out>, argc=argc@entry=1, argv=argv@entry=0x7fffffffd4a8, env=env@entry=0xbcf5c0) at dl-init.c:72
#2 0x00007ffff7de77cb in call_init (env=0xbcf5c0, argv=0x7fffffffd4a8, argc=1, l=<optimized out>) at dl-init.c:30
#3 _dl_init (main_map=main_map@entry=0xfc9390, argc=1, argv=0x7fffffffd4a8, env=0xbcf5c0) at dl-init.c:120
#4 0x00007ffff7dec8e2 in dl_open_worker (a=a@entry=0x7fffffffaf30) at dl-open.c:575
#5 0x00007ffff7de7564 in _dl_catch_error (objname=objname@entry=0x7fffffffaf20, errstring=errstring@entry=0x7fffffffaf28, mallocedp=mallocedp@entry=0x7fffffffaf1f, operate=operate@entry=0x7ffff7dec4d0 <dl_open_worker>, args=args@entry=0x7fffffffaf30) at dl-error.c:187
#6 0x00007ffff7debda9 in _dl_open (file=0x7fffe99d40c0 "/usr/local/lib/python3.5/dist-packages/torch/_C.cpython-35m-x86_64-linux-gnu.so", mode=-2147483391, caller_dlopen=0x60b35a <_PyImport_FindSharedFuncptr+138>, nsid=-2, argc=<optimized out>, argv=<optimized out>, env=0xbcf5c0) at dl-open.c:660
#7 0x00007ffff75ecf09 in dlopen_doit (a=a@entry=0x7fffffffb160) at dlopen.c:66
#8 0x00007ffff7de7564 in _dl_catch_error (objname=0xa7f8b0, errstring=0xa7f8b8, mallocedp=0xa7f8a8, operate=0x7ffff75eceb0 <dlopen_doit>, args=0x7fffffffb160) at dl-error.c:187
#9 0x00007ffff75ed571 in _dlerror_run (operate=operate@entry=0x7ffff75eceb0 <dlopen_doit>, args=args@entry=0x7fffffffb160) at dlerror.c:163
#10 0x00007ffff75ecfa1 in __dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:87
```

どうやら共有ライブラリのロードのところでコケているようです。さらに詳しくみてみると、"/usr/local/lib/python3.5/dist-packages/torch/_C.cpython-35m-x86_64-linux-gnu.so" のところで失敗している模様。

私の環境でこの共有ライブラリが呼び出しているライブラリを ldd で見てみると、

```console
shell$ ldd /usr/local/lib/python3.6/dist-packages/torch/_C.cpython-36m-aarch64-linux-gnu.so
        linux-vdso.so.1 (0x0000007fa9798000)
        libtorch_python.so => /usr/local/lib/python3.6/dist-packages/torch/lib/libtorch_python.so (0x0000007fa8df9000)
        libshm.so => /usr/local/lib/python3.6/dist-packages/torch/lib/libshm.so (0x0000007fa8ddf000)
        libtorch.so => /usr/local/lib/python3.6/dist-packages/torch/lib/libtorch.so (0x0000007fa637d000)
        libc10.so => /usr/local/lib/python3.6/dist-packages/torch/lib/libc10.so (0x0000007fa6328000)
        libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000007fa62e9000)
        libstdc++.so.6 => /usr/lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000007fa6156000)
        libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000007fa6132000)
        libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007fa5fd9000)
        /lib/ld-linux-aarch64.so.1 (0x0000007fa976d000)
        librt.so.1 => /lib/aarch64-linux-gnu/librt.so.1 (0x0000007fa5fc2000)
        libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000007fa5f08000)
        libnuma.so.1 => not found
        libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000007fa5ef3000)
        libopenblas.so.0 => /usr/lib/aarch64-linux-gnu/libopenblas.so.0 (0x0000007fa582b000)
        libnuma.so.1 => not found
        libgfortran.so.4 => /usr/lib/aarch64-linux-gnu/libgfortran.so.4 (0x0000007fa5727000)
 ```

なんか、libnuma.so.1 が not found になってました。
libnuma.so.1 が入っているパッケージを調べてみると、libnuma1 でした。

```console
shell$ apt-file search libnuma.so.1
libnuma1: /usr/lib/aarch64-linux-gnu/libnuma.so.1
libnuma1: /usr/lib/aarch64-linux-gnu/libnuma.so.1.0.0
```

libnuma1 をインストールして無事解決。

# 所感(というか愚痴)

いくらなんでも Segmentation fault は無いだろう。。。せめて、これこれの共有ライブラリが見つからないとかメッセージ出してくれ。。。

Python のパッケージ管理と Debian のパッケージ管理の連携がとれてないのも、ちょっと不満。pip で Python のパッケージをインストールする際に、Python のパッケージが必要とする Debian のパッケージの情報があれば良かったのに。。。ついでにその際に Debian のパッケージもインストールしてくれれば、もっと良いかも。まあ、Debian 以外の他の OS のパッケージ管理との関連もあるし難しいのかもしれないけど。