エンジニアとしての市場価値を測りませんか?PR

企業からあなたに合ったオリジナルのスカウトを受け取って、市場価値を測りましょう

14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

FortranAdvent Calendar 2021

Day 1

Fortranの標準ライブラリstdlibの紹介

Last updated at Posted at 2021-11-30

概要

Fortran-langコミュニティが主導して開発しているFortraの標準ライブラリstdlibについて紹介します.紹介する内容は,stdlibの現行バージョン0.1.0に基づいています.

本記事はstdlibの紹介を主眼にしており,その狙いやインストール方法などを解説します.stdlibの各機能の使用例は別の記事で紹介し,本記事にリンクしていきます.

stdlibのねらい

Fortranには,規格で定められた標準ライブラリがありません.そのため,必須と思われる処理があちこちで再発明されていました.stdlibは,コミュニティ主導で,コミュニティによって合意された事実上の標準ライブラリを提供することを目的としています.

Issueでも議論されていましたが,stdlib自身は車輪の再発明を含んでいます.しかし,コミュニティによって合意された車輪を開発することにより,それが多くの人に適合し,個別の再発明を回避できます.

また,stdlibに実装された機能のうち,いくつかを標準に取り込もうという動きもあるようです.

stdlibの対象範囲

stdlibは,三つの対象を掲げています.各対象での開発項目と,それらの現状を列挙します.

  • Utilities
    • containers
      文字列を扱うためのユーザ定義派生型string_typestring_typeのリストstringlist_typeが実装されている.連結リストもレビュー中である.
    • strings
      文字および文字列に対する処理がstdlib_ascii, stdlib_stringsに実装されている.
    • files
      stdlib_ioに,ファイルオープンや簡潔な入出力を実行する処理が実装されている.
    • OS/environment integration
      機能は多くないが,stdlib_systemstdlib_errorに標準よりも柔軟な機能が実装されている.型のkindが定義されたモジュールstdlib_kindsも用意されている.
    • unit testing & assertions
      単体テストの機能は,stdlibとは切り離された状態で開発されているが,stdlibのテストに利用されている.stdlibに取り込むかどうかの議論もされている.assertionsに関する簡単か機能がstdlib_errorに実装されている.
    • logging
      stdlib_loggerにロギングのための派生型が定義されている.
    • その他
      optional引数の取り扱いを改善するoptvalが実装されている.
  • Algorithms
    • searching
      現状該当なし
    • sorting
      stdlib_sortingに2種類のソートが実装されている.
    • merging
      現状該当なし
  • Mathematics
    • linear algebra
      stdlib_linalgに簡単な処理が実装されている.
    • sparse matrices
      現状該当なし.議論はされており,stdlibリポジトリのWikiにSparse matrix APIが確認できる.
    • special functions
      stdlib_specialfunctionsにLegendre多項式が実装されている.
    • fast Fourier transform
      現状該当なし
    • random numbers
      stdlib_randomに整数擬似乱数生成器が実装されている.
    • statistics
      stdlib_statsに平均値,中央値,分散,共分散,相関係数,モーメントの計算が実装されている.
      stdlib_stats_distribution_uniformに一様分布,確率密度関数,累積分布関数などが実装されている.
    • ordinary differential equations
      現状該当なし
    • numerical integration
      stdlib_quadratureに台形則,シンプソン則,Gauss-Legendre求積法,Gauss-Legendre-Lobatto求積法が実装されている.
    • optimization
      現状該当なし

stdlibのビルドとインストール

要求ソフトウェア

stdlibのビルドには,Fortran 2008以降のコンパイラが必須です.その他は,ビルドする環境によって異なります.

ビルドにCMakeを利用する場合は,

  • CMake 3.14以降
  • makeもしくはNinja
  • fypp

が必要です.CMakeを用いず,makeのみでビルドすることも可能ですが,その場合でもfyppは必要です.

ビルドにfpm(Fortran-langによって開発されているFortran用のパッケージマネージャ兼ビルドツール)を用いる場合は,

  • fpm 0.4.0以降
  • リンカ
    • 例えばWindows版Intel FortranであればVisual Studio

が必要です.

ソースの取得

GitHubからソースを取得します.

git clone https://github.com/fortran-lang/stdlib

以降の作業は,stdlibディレクトリで行うことを前提としています.

cd stdlib

ビルドとインストール

CMakeによるビルドとインストール

CMakeは,2段階でビルドを行います.まず,下記のコマンドを実行してビルドの設定を行います.

cmake -B build

設定段階では,いくつかオプションが指定できます.

  • CMakeのオプション
    • -DCMAKE_Fortran_COMPILER=コンパイラ
      ビルドに用いるコンパイラを指定する.コンパイラの部分はコンパイラの実行コマンド(gfortranの場合はgfortran,Intel Fortranの場合はifort)に置き換える.
    • -G バックエンド
      ビルド・リンクに用いるバックエンド(ジェネレータ)を指定する.WindowsでVisual Studioをインストールしていると,Visual Studioが標準のバックエンドとなる.明示的にmakeを指定するには,-G "Unix Makefiles"を与える.
  • stdlibのオプション
    • -DCMAKE_MAXIMUM_RANK:String=ランク
      fyppによって生成される,手続の引数となる配列の最大ランクを指定する.最大値は15,標準値は4である. ランクを15としてコンパイルすると,4 GB程度のメモリを消費する.並列ビルドの場合は,並列数に比例して使用メモリ量が増加する.
      利用者は多くないと思うが,CMakeLists.txtを編集してVisual Studioをバックエンドに利用すると,ランク15としてビルドした際に完了まで数時間を要する.
    • -DBUILD_SHARED_LIBS={ON|OFF}
      出力するライブラリの種類を制御する.ONの場合は共有ライブラリ,それ以外では静的ライブラリを生成する.

設定が完了した後,ターゲットをビルドします.

cmake --build build

ビルドしたライブラリおよびmodファイルをインストールするには,

cmake --install build

を実行します.このとき,--prefixオプションでインストールディレクトリを指定しないと,標準のインストールディレクトリにインストールされます.標準ディレクトリは,Unix系OSの場合は/usr/local,Windowsの場合はC:/Program Files/です.Unix系OSでもWindowsでも,標準のディレクトリへのファイルコピーに管理者権限が必要なので,管理者として作業していない場合はインストールに失敗します.

CMake Error at build/config/cmake_install.cmake:41 (file):
  file cannot create directory: /usr/local/lib/pkgconfig.  Maybe need
  administrative privileges.

CMakeを利用してインストールすると,ライブラリlibfortran_stdlib.aがインストールディレクトリ直下のlibディレクトリにコピーされます.また,インストールディレクトリ直下のinclude/fortran_stdlib/コンパイラベンダ-バージョン.modおよび.smodファイルがコピーされます.

コンパイラベンダ-バージョンについては,例えばgfortran 9.3.0でビルドするとGNU-9.3.0となります.

fpmによるビルドとインストール

stdlibには,fpmでビルドするための設定が追加されたブランチstdlib-fpmが存在します.当該ブランチをチェックアウトして,ビルド・インストールを行うことになります.

git switch stdlib-fpm

stdlib-fpmブランチに用意されているビルド設定(マニフェスト)fpm.tomlには,インストールの設定が書かれておらず,インストールに失敗します.そのため,次の項目をfpm.tomlに追記します.

[install]
library = true

追加した後,ビルドを行います.

fpm build --profile release

ビルドが完了したら

fpm install --profile release --prefix インストールディレクトリ

を実行してインストールします.このとき,インストールディレクトリ直下のlibディレクトリにライブラリlibstdlib.aが,include.modファイルがコピーされます.CMakeでビルドする時とライブラリの名前が異なることに注意してください.

stdlibの利用

CMakeを利用してstdlibをインストールし,stdlibを参照するプログラムをCMakeでビルドする場合は,CMakeLists.txt内でfind_package(fortran_stdlib REQUIRED)を呼び出した後,target_link_librariesの項目にfortran_stdlib::fortran_stdlibを追加します.

CMakeおよびfpm以外を用いてビルドする場合は,libおよびincludeディレクトリにパスを通しておき,ライブラリとしてfortran_stdlibを参照します.

fpmを利用してビルドする場合は,libおよびincludeディレクトリにパスを通しておき,fpm.tomlのbuildセクションに,linkexternal-modulesの設定を追加します.

[build]
link = "stdlib"
external-modules = ["stdlib_error", "stdlib_kinds"]

上記の例は,stdlib_errorおよびstdlib_kindsモジュールをuseしている場合の設定です.他にもstdlibのモジュールをuseしている場合は,そのモジュールの名前を追加する必要があります.

fpmの設定ファイルに下記の設定を記述すると,stdlibをシステムにインストールしていなくても,stdlibをGitHubリポジトリから取得して参照できます.この設定を利用すると,上記のlinkexternal-modulesの設定が不要になるので,非常に便利です.

[dependencies]
stdlib = { git="https://github.com/fortran-lang/stdlib", branch="stdlib-fpm" }

fpmの使い方に関しては,fpm (Fortran Package Manager)の使い方fpm (Fortran Package Manager)の設定ファイルの解説等をご覧ください.

stdlib_versionの使用例

stdlibに新しく追加されたモジュールstdlib_versionの紹介も兼ねて,利用方法の例を示します.

stdlib_versionは,Fortranの標準ライブラリstdlibのバージョンを提供します.バージョン番号はセマンティックバージョニングに基づいており,定数として参照することも,ゲッターから取得することもできます.

stdlib.f90
module stdlib
    use :: stdlib_version
    implicit none
    private
    public :: version

contains

    subroutine version()
        implicit none
        block
            ! バージョン番号の定数を参照する.
            print *, stdlib_version_string
            ! 0.1.0

            ! バージョン番号を単一の整数として取得する.
            ! version_compact = major*10000 + minor*100 + patchで取得する
            print '(I6.6)', stdlib_version_compact
            ! 000100
        end block
        block
            character(:), allocatable :: ver
            ! stdlibのバージョンを文字列で取得する.
            call get_stdlib_version(string=ver)
            print *, ver
            ! 0.1.0
        end block

        block
            use, intrinsic :: iso_fortran_env
            integer(int32) :: major, minor, patch

            ! stdlibのバージョン番号(major, minor, patch)を個別に取得する.
            call get_stdlib_version(major=major, minor=minor, patch=patch)
            print '(*(g0:,"."))', major, minor, patch
            !0.1.0
        end block
    end subroutine version
end module stdlib
main.f90
program main
    use :: stdlib
    implicit none

    call version()
end program main

CMake

CMakeを用いてstdlibをビルド・インストールしてある場合に,上記のソースファイルをCMakeによってビルドするには,上述のとおりCMakeLists.txt内でfind_package(fortran_stdlib REQUIRED)を呼び出した後,target_link_librariesの項目にfortran_stdlib::fortran_stdlibを追加します.

stdlibのインストールディレクトリにパスが通ってい場合,変数CMAKE_PREFIX_PATHにstdlibのインストールディレクトリを追加するか,変数fortran_stdlib_DIRfortran_stdlib-config.cmakeが存在するディレクトリパスを指定します.

例えば,下記のようにインストールした場合,

cmake --install build --prefix C:\Users\ユーザ名\AppData\Local\fortran_stdlib\

CMakeLists.txtは次のように作成します.

CMAKELists.txt
cmake_minimum_required(VERSION 3.14.0)
project(stdlib_ver LANGUAGES Fortran)

set(fortran_stdlib_DIR "C:/Users/ユーザ名/AppData/Local/fortran_stdlib/lib/cmake/fortran_stdlib")
find_package(fortran_stdlib REQUIRED)

add_executable(${PROJECT_NAME}
    main.f90
    stdlib.f90
)

target_link_libraries(${PROJECT_NAME}
    PRIVATE
    fortran_stdlib::fortran_stdlib
)
cmake -B build
cmake --build build
build\stdlib_ver.exe
 0.1.0
000100
 0.1.0
0.1.0

fpm

fpmを用いると,設定が簡単になります.下記コマンドでfpmのプロジェクトを新規作成し,上記のmain.f90およびstdlib.f90を,それぞれapp, srcディレクトリにコピーします.

fpm new stdlib_ver --app --lib

その後,設定ファイルfpm.toml[dependencies]の設定を追記してビルド・実行します.

name = "stdlib_ver"
version = "0.1.0"
license = "license"
author = "Jane Doe"
maintainer = "jane.doe@example.com"
copyright = "Copyright 2021, Jane Doe"
[build]
auto-executables = true
auto-tests = true
auto-examples = true
[install]
library = false
[dependencies]
stdlib = { git="https://github.com/fortran-lang/stdlib", branch="stdlib-fpm" }
fpm build
fpm run
 0.1.0
000100
 0.1.0
0.1.0
14
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up

Qiita Advent Calendar is held!

Qiita Advent Calendar is an article posting event where you post articles by filling a calendar 🎅

Some calendars come with gifts and some gifts are drawn from all calendars 👀

Please tie the article to your calendar and let's enjoy Christmas together!

14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Login to continue?

Login or Sign up with social account

Login or Sign up with your email address