【Fortran】OpenBLAS環境構築

# はじめに
この記事は、Arch LinuxでのOpenBLAS環境構築について述べています。
Windowsでは、同様の手順での環境構築はできません。また、他のUNIX系OSでも、同様の方法では環境構築できない可能性があります。

# 目標
OpenBLASの関数やサブルーチンを含むFortranプログラムに、コンパイラを用いてライブラリをリンクし、実行できるようにする。

# 実行環境
2024年11月6日に、環境構築を行った。
システム情報は、以下の通り。
 ```
 $ neofetch
                   -`                    username@archlinux.local 
                  .o+`                   -------------------- 
                 `ooo/                   OS: Arch Linux x86_64 
                `+oooo:                  Host: HP Spectre x360 Convertible 13-aw0xxx 
               `+oooooo:                 Kernel: 6.11.6-arch1-1 
               -+oooooo+:                Uptime: 10 mins 
             `/:-:++oooo+:               Packages: 858 (pacman) 
            `/++++/+++++++:              Shell: bash 5.2.37 
           `/++++++++++++++:             Resolution: 1920x1080 
          `/+++ooooooooooooo/`           DE: Plasma 6.2.3 
         ./ooosssso++osssssso+`          WM: kwin 
        .oossssso-````/ossssss+`         Theme: Adwaita [GTK3] 
       -osssssso.      :ssssssso.        Icons: Adwaita [GTK3] 
      :osssssss/        osssso+++.       Terminal: konsole 
     /ossssssss/        +ssssooo/-       CPU: Intel i7-1065G7 (8) @ 3.900GHz 
   `/ossssso+/:-        -:/+osssso+-     GPU: Intel Iris Plus Graphics G7 
  `+sso+:-`                 `.-/+oso:    Memory: 2640MiB / 15671MiB 
 `++:.                           `-/+/
 .`                                 `/                           
                                                                 
 ```
また、Cコンパイラにはgcc、Fortranコンパイラにはgfortranを用いた。
 
```
$ gcc --version
gcc (GCC) 14.2.1 20240910
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ gfortran --version
GNU Fortran (GCC) 14.2.1 20240910
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
```

# OpenBLASのダウンロード
OpenBLASのgithubレポジトリのReleasesから、最新のものをダウンロードした。2024年11月6日現在、最新版は0.3.28（リリース日：2024年8月9日）。ファイルが複数あるうち、「OpenBLAS-0.3.28.tar.gz」のみダウンロードした。

https://github.com/OpenMathLib/OpenBLAS

tarコマンドで解凍する。
```
$ tar -zxvf OpenBLAS-0.3.28.tar.gz
```
# ビルド・インストール

## Makefile.ruleの編集

解凍後のディレクトリに移動する。
 ```
 $ cd OpenBLAS-0.3.28
 ```
 テキストエディタを起動し、Makefile.ruleを編集する。
 編集した箇所は以下の通り。

・Fortranコンパイラを指定
```
# Fortran compiler. Default is g77.
FC = gfortran
```

・C言語用のインターフェースの除外
```
# If you don't need the CBLAS interface, please comment this in.
NO_CBLAS = 1
```

・LAPACKのビルドの除外
```
# If you don't need LAPACK, please comment this in.
# If you set NO_LAPACK=1, the build system automatically sets NO_LAPACKE=1.
NO_LAPACK = 1
```

・最適化フラグの設定
```
# Common Optimization Flag;
# The default -O2 is enough.
# Flags for POWER8 are defined in Makefile.power. Don't modify COMMON_OPT
COMMON_OPT = -O3
```

・再帰オプションの設定
```
# gfortran option for LAPACK to improve thread-safety
# It is enabled by default in Makefile.system for gfortran
# Flags for POWER8 are defined in Makefile.power. Don't modify FCOMMON_OPT
FCOMMON_OPT = -frecursive
```
## ビルド
makeを実行。数分待つ。
```
$ make
```

## インストール
ビルド後、以下のコマンドを実行して、/opt/OpenBLAS/ に、必要なオブジェクトファイルなどを配置する。
```
# make install
```

## 環境変数の設定
動的ライブラリ（生成されたsoファイル）を使用する場合、プログラムの実行中に参照するため、環境変数の設定が必要。一時的に使用する場合は、次のコマンドで十分。
```
$ export LD_LIBRARY_PATH=/opt/OpenBLAS/lib:$LD_LIBRARY_PATH
```
今回は、システム全体の環境変数として、永続的に使うための設定をする。
```:/etc/environment
#
# This file is parsed by pam_env module
#
# Syntax: simple "KEY=VAL" pairs on separate lines
#

LD_LIBRARY_PATH=/opt/OpenBLAS/lib:$LD_LIBRARY_PATH
```
以上のように、/etc/environment を設定したのち再起動。

# 実行例
以上で環境構築が完了したはずなので、プログラムをコンパイル、実行してみる。
（ちなみに、ライブラリの中にある関数の使い方が分からず詰まっていたが、プログラム内で型の宣言をすればそのまま使えるようである。）
```fortran:ddot_test.f90
program main
    use, intrinsic :: iso_fortran_env
    implicit none
    
    ! OpenBLASの関数
    real(real64) :: ddot

    integer(int32) :: n_dim, incx, incy
    real(real64) :: vec_x(4), vec_y(4)

    n_dim = 4
    incx = 1
    incy = 1
    vec_x = [1.0d0, 2.0d0, 3.0d0, 4.0d0]
    vec_y = [5.0d0, 6.0d0, 7.0d0, 8.0d0]

    print '(f8.3)', ddot(n_dim, vec_x, incx, vec_y, incy)

end program main

```

```:コンパイル
$ fortran -o ddot_test.out ddot_test.f90 -L/opt/OpenBLAS/lib/ -lopenblas
```

```:実行
$ ./ddot_test.out 
  70.000
```

確かに、1\*5 + 2\*6 + 3\*7 + 4\*8 = 70 と計算されている。

# 参考
FortranコードにBLASをリンクする（アクセス日：2024年11月6日）：https://qiita.com/Yasushi-Shinohara/items/d81201912324d85dab5f