Vim で Unicode 記号の入力補完をする

Julia 言語の特徴の一つとして広範な Unicode 記号を識別子として使える、というものがあります。その有用性について最初は懐疑的だったのですが、一度使ってしまうともう戻れなくなりました。過去のコードが mu だの theta だの phi だので埋め尽くされているのをみると、そっと vim を閉じたくなります。

さて、問題はこれらの記号をいかにして入力するか、ということです。Julia REPL では Tab キーを使い、\ から始まる LaTeX っぽい記法から変換することができます。例えば、

  1. \alp --Tab--> \alpha
  2. \alpha --Tab--> α

といった具合です。julia-vim が同様の機能を vim 上で実現していて非常に助かるんですけど、私思うんです、vim にはポップアップウィンドウがあるんだから \alpha を経由する必要なくない…?って。

というわけで書きました。

github.com

asyncomplete-unicodesymbol.vim

注意する点としては julia-vim と asyncomplete.vim v2 branch が必要なことです。リリースまでもうすこしらしいんですけど、よかったらデバッグに参加してみましょう。

(※ 2019/4/2 追記 asyncomplete.vim v2 無事リリースされました!今は master branch を使えば大丈夫です。)

さらに、当然といえば当然なのですが \alphaα に文字列としてはマッチしていません。このような補完 (変換?) をおこなうために、補完要素のフィルターをいじる必要があります。asyncomplete は v2 からこの部分をカスタマイズできるようになりました。わかる人は自分で何とかしてください。よくわからん、という人は asyncomplete-ezfilter.vim を使ってください。これは asyncomplete で complete-source 毎にフィルタをかけるためのプラグインです。まとめるとこんな感じです。

let g:asyncomplete_preprocessor =
  \ [function('asyncomplete#preprocessor#ezfilter#filter')]

autocmd User asyncomplete_setup call asyncomplete#register_source(
  \ asyncomplete#sources#unicodesymbol#get_source_options({
  \   'name': 'unicodesymbol',
  \   'whitelist': ['julia'],
  \   'completor': function('asyncomplete#sources#unicodesymbol#completor'),
  \ }))

let g:asyncomplete#preprocessor#ezfilter#config = {}
let g:asyncomplete#preprocessor#ezfilter#config.unicodesymbol =
  \ {ctx, items -> filter(items, 'ctx.match(v:val.menu)')}

Julia の Language server を Vim でうごかす

やっと、 LanguageServer.jl を動かせるようになったのでまとめます。将来はもっと簡単になると思いますが、とりあえず。

Julia 側の準備

まずなんですが、現在 (2019/2/9) の時点では [LanguageServer.jl] は Julia v1.1.0 では正常に動作しないようです。なので、別に v1.0.3 をインストールします。この時、パスを通す必要はありません。

次に LanguageServer.jlSymbolServer.jl をインストールします。Julia v1.0.3 を起動し ]add LanguageServer SymbolServer と実行します。SymbolServerLanguageServer の依存に入っているはずなんですけど、なぜか後で手動読み込みする必要があるので、明示的にインストールします。今のところ LanguageServer は v"0.5.1" 、SymbolServer は v"0.1.2" で動作確認しています。

※ --- 2019/4/4 追記 ---

SymbolServer.jl が v"0.1.3" に更新され、julia 1.1.0 でも動作するようになりました🎉

※ --- 2019/4/4 追記ここまで ---

f:id:machakann:20190209152230p:plain

LanguageServer の起動スクリプト startlanguageserver.jl を保存しておきます。このファイルパスをのちに vimrc に書く必要があります。

  • startlanguageserver.jl
import LanguageServer
import Pkg
import SymbolServer

envpath = dirname(Pkg.Types.Context().env.project_file)

const DEPOT_DIR_NAME = ".julia"
depotpath = if Sys.iswindows()
    joinpath(ENV["USERPROFILE"], DEPOT_DIR_NAME)
else
    joinpath(ENV["HOME"], DEPOT_DIR_NAME)
end

server = LanguageServer.LanguageServerInstance(stdin, stdout, false, envpath, depotpath, Dict())
server.runlinter = true
run(server)

これで Julia 側の準備は終わりです。試しに include("path/to/startlanguageserver.jl") を実行してエラーが出ないか確かめましょう。

f:id:machakann:20190209152928p:plain

Vim 側の準備

vim-lsp と必要なプラグインをインストールします。

Plug 'prabirshrestha/async.vim'
Plug 'prabirshrestha/vim-lsp'

vim-lsp の README から引用しました。vim-plug を使った例のようですね。好きなプラグインマネージャを使うように読み替えましょう。自動補完が必要なら追加でいくつか必要です。

Plug 'prabirshrestha/asyncomplete.vim'
Plug 'prabirshrestha/async.vim'
Plug 'prabirshrestha/vim-lsp'
Plug 'prabirshrestha/asyncomplete-lsp.vim'

最後に次の設定を vimrc に追加します。実行ファイルと起動スクリプトのパスを指定する必要があります。(s:julia_exe 及び s:julia_lsp_startscript)

let s:julia_exe = 'path/to/julia-1.0.3-executable'
let s:julia_lsp_startscript = 'path/to/startlanguageserver.jl'
if executable('julia')
  autocmd User lsp_setup call lsp#register_server({
  \ 'name': 'julia',
  \ 'cmd': {server_info->[s:julia_exe, '--startup-file=no', '--history-file=no', s:julia_lsp_startscript]},
  \ 'whitelist': ['julia'],
  \ })
endif

以上で終わりです。

使用に関して

*.jl なファイルを開くと起動します。起動に少し時間がかかるようなので気長に待ちましょう。わたしのノートPCだと20秒ぐらいかかります。補完はさらにインサートモードに入って何文字かタイプした後、7~8 秒待って次にインサートモードに入るときにはじまるようです。

全部の機能が動いているかはまだ試していません。SymbolServer は結局動いているか微妙な感じもします。

f:id:machakann:20190209155720g:plain

※ 2018/2/10 追記 : リネーム機能は動いてない模様。あとでもうちょっと調べます。vscode だと動くんだけどな…

Julia で Grass-Fire algorithm を書く

なんの因果か最近は画像をぐりぐりしています。

画像の明るい点を検知してその重心位置を求める必要ができたのですが、考えてみるとなかなか難しい。いろいろ調べてみるとどうやらこういうのは BLOB (Binary Large OBject) detection というらしいです。厳密には BLOB extraction かな。

単純でいいのでとにかく速いものが欲しい、ということで探しているとここの Grass-Fire algorithm 解説を見つけました。どうも一次情報は [T. B. Moeslund, Introduction to Video and Image Processing: Building Real Systems and Applications, Springer London, London, 2012.] という本みたいですが、引用とかないし大丈夫かこれ。幸い、本を図書館で利用できたので参考にしました。

ちなみに真っ先に試したのはImages.jlblob_LoG 関数なんですが、ちょっとほしいものと違う感じでした。BLOBの中心は得られるのですが、できればサブピクセルレベルで、つまり小数点以下のレベルで座標を欲しかったんです。よく理解していないだけかもしれないです。OpenCV とかに便利で速い関数とかありそうなんですが、今のところ julia から OpenCV を使うのは簡単ではなさそう…。Grass-Fire algorithm は経路探索など様々な用途で使われるもののようです。とりあえず私の目的も果たせそうなのでいいでしょう。

いかにも再帰が向いていそうな感じなので、とりあえずその方向で書きました。閾値の thr と同じかより大きい値を持つピクセルの連続を BLOB として認識し、座標の配列として返します。

function extractblob_rec(img, thr)
    height, width = size(img)
    checked = fill!(similar(img, Bool), false)
    bloblist = Vector{NTuple{2,Int}}[]
    for x in 1:width, y in 1:height
        # Scan pixels until a new BLOB
        @inbounds if img[y, x] >= thr && !checked[y, x]
            # BLOB detection by Grass-Fire algorithm
            blob = NTuple{2,Int}[]
            grassfire!(blob, checked, img, y, x, thr)
            push!(bloblist, blob)
        end
    end
    bloblist
end


function grassfire!(blob, checked, img, y, x, thr)
    height, width = size(img)
    push!(blob, (y, x))
    checked[y, x] = true

    # check the below pixel
    if y+1 <= height && img[y+1, x] >= thr && !checked[y+1, x]
        grassfire!(blob, checked, img, y+1, x, thr)
    end

    # check the right pixel
    if x+1 <= width && img[y, x+1] >= thr && !checked[y, x+1]
        grassfire!(blob, checked, img, y, x+1, thr)
    end

    # check the upper pixel
    if y-1 >= 1 && img[y-1, x] >= thr && !checked[y-1, x]
        grassfire!(blob, checked, img, y-1, x, thr)
    end

    # check the left pixel
    if x-1 >= 1 && img[y, x-1] >= thr && !checked[y, x-1]
        grassfire!(blob, checked, img, y, x-1, thr)
    end
    blob
end

参考と同じ簡単な 6x5 の配列を作ってテストしてみます。

julia> img
6×5 Array{Int64,2}:
 0  0  1  1  1
 0  0  0  1  0
 0  0  0  1  0
 0  1  1  0  0
 0  1  1  0  0
 0  1  1  0  0

julia> extractblob_rec(img, 1)
2-element Array{Array{Tuple{Int64,Int64},1},1}:
 [(4, 2), (5, 2), (6, 2), (6, 3), (5, 3), (4, 3)]
 [(1, 3), (1, 4), (2, 4), (3, 4), (1, 5)]

二つの BLOB を見つけたみたいです、よさそうですね。探す様子を GIF 化しました。赤が走査している場所、緑と青が BLOB です。

f:id:machakann:20190203222610g:plain
GrassFireAlgorithm


さて、再帰を使っていると StackOverflowError が怖いです。たしか Julia ではまだ末尾呼び出し最適化されないので、BLOB が大きくなるとスタックがあふれます。私の実際の用途を考えると BLOB のサイズはそんなに大きくならないのですが、いちおう再帰を使わない形も考えてみます。

import DataStructures: Stack

function extractblob_loop(img, thr)
    height, width = size(img)
    stack = Stack{NTuple{3,Int}}()
    checked = fill!(similar(img, Bool), false)
    bloblist = Vector{NTuple{2,Int}}[]
    for x in 1:width, y in 1:height
        # Scan pixels until a new BLOB
        @inbounds if img[y, x] < thr || checked[y, x]
            # BLOB detection by Grass-Fire algorithm
            # NOTE: re-use `stack` because making a new one is a little costly
            blob = grassfire_loop!(checked, stack, img, y, x, thr)
            push!(bloblist, blob)
        end
    end
    bloblist
end


function grassfire_loop!(checked, stack, img, y0, x0, thr)
    height, width = size(img)
    blob = NTuple{2,Int}[]
    push!(stack, (y0, x0, 4))
    push!(blob, (y0, x0))
    checked[y0, x0] = true
    while !isempty(stack)
        y, x, state = pop!(stack)
        checked[y, x] = true

        # check the below pixel
        if state >= 4 && y+1 <= height && img[y+1, x] >= thr && !checked[y+1, x]
            push!(stack, (y, x, 3))
            push!(stack, (y+1, x, 4))
            push!(blob, (y+1, x))
            continue
        end

        # check the right pixel
        if state >= 3 && x+1 <= width && img[y, x+1] >= thr && !checked[y, x+1]
            push!(stack, (y, x, 2))
            push!(stack, (y, x+1, 4))
            push!(blob, (y, x+1))
            continue
        end

        # check the upper pixel
        if state >= 2 && y-1 >= 1 && img[y-1, x] >= thr && !checked[y-1, x]
            push!(stack, (y, x, 1))
            push!(stack, (y-1, x, 4))
            push!(blob, (y-1, x))
            continue
        end

        # check the left pixel
        if state >= 1 && x-1 >= 1 && img[y, x-1] >= thr && !checked[y, x-1]
            push!(stack, (y, x, 0))
            push!(stack, (y, x-1, 4))
            push!(blob, (y, x-1))
            continue
        end
    end
    blob
end

ランダムな配列でテストしたところ extractblob_rec と同じ結果を返すようです。

次に 800x600 ピクセルに50個程度の輝点を持つ画像を用意し、性能を確認しました。ベンチマークの結果は以下です。

julia> versioninfo()
Julia Version 1.1.0
Commit 80516ca202 (2019-01-21 21:24 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.1 (ORCJIT, broadwell)

julia> using BenchmarkTools

julia> @benchmark extractblob_rec(testimg, 240)
BenchmarkTools.Trial:
  memory estimate:  482.02 KiB
  allocs estimate:  135
  --------------
  minimum time:     408.409 μs (0.00% GC)
  median time:      453.314 μs (0.00% GC)
  mean time:        515.280 μs (4.78% GC)
  maximum time:     60.672 ms (98.67% GC)
  --------------
  samples:          9601
  evals/sample:     1

julia> @benchmark extractblob_loop(testimg, 240)
BenchmarkTools.Trial:
  memory estimate:  506.22 KiB
  allocs estimate:  140
  --------------
  minimum time:     409.692 μs (0.00% GC)
  median time:      454.168 μs (0.00% GC)
  mean time:        512.038 μs (5.07% GC)
  maximum time:     58.005 ms (99.16% GC)
  --------------
  samples:          9665
  evals/sample:     1

800x600 の画像で 1ms を切るのが目標だったので、とりあえずどちらも目標達成ですね。非力なノート PC で達成できたので十分といえるでしょう。使用メモリーのほとんどが checked 配列に費やされているので、これを再利用すると 1/10 ぐらいになります。median time を見ると再帰を使ったほうがちょっと速そうに見えますが誤差です。何回か測定すると前後します。

最終的には再帰のほうがコードは簡潔ですけど、ちょっと悩みます。どっちを使うべきか…。あと、まだどこか高速化する余地はあるか考えてみます。重心位置の計算は省略。

けものフレンズのタイトルロゴのアレ

vim-colorscheme-kemonofriends を書いたときに、けものフレンズのタイトルロゴを Vim バッファ上に出力するスクリプトを (README に載せるためだけに) 書きました。例のスクリーンショットを撮った後、当のスクリプトはどこに置いたのかわからなくなってしまって間違って消したのかと思っていたんですけど、さっきひょんなことから見つけたので gist に置くことにしました。

kemologo.vim

使い方は簡単で、vim-colorscheme-kemonofriendsをインストールして

:source kemologo.vim
:KemonofriendsLogo

これだけです。

f:id:machakann:20180923014202g:plain

BLAS ライブラリの違いによる GAMESS のパフォーマンス比較

GAMESS に BLAS ライブラリとして mkl, OpenBLAS, ATLAS をリンクした場合のパフォーマンスを比較しました。

参考 :
GAMESS をビルドする mkl 編
GAMESS をビルドする OpenBLAS 編

ATLAS もビルドしようとしてみたんですけど CPU throttling の停止ができなくて諦めました…。代わりに apt でインストールしたものを使っていますが、環境に最適化されたものでないことは留意してください。

sudo apt-get install libatlas-base-dev

CC や MP2 の計算で BLAS の差が出るときいたので、そのへんを試してみました。正直こういう計算はやったことがなく、マニュアルとかを読みながらやっていますが、妥当なインプットファイルを作れているか自信はないです。

環境

CPU: Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz
MEMORY: 16 GB
OS : Ubuntu 18.04 64bit
gcc : version 7.3.0
GAMESS : Feb 14, 2018 R1 Public Release
BLAS : mkl (intel-mkl-2018.3-051), OpenBlas v0.3.3, ATLAS (libatlas-base-dev_3.10.3-5_amd64)

Alanine の Single Point Energy - CCSD(T)/6-311G

インプットファイルはこちら

三回ずつ計算を走らせて、その中の最も良かった TOTAL WALL CLOCK TIME を比較しました。単位は秒です。結果は mkl が最も速かったものの、OpenBLAS がかなり善戦しているという結果でした。ATLAS については自分でビルドしたものではないので、その性能を出しきれてないというのはあると思います。

f:id:machakann:20180916203850j:plainf:id:machakann:20180921222253p:plain
The Computing Time of Alanine Single Point Energy

Caffeine の Single Point Energy - MP2/6-311G(d)

インプットファイルはこちら

同じく、三回ずつ計算を走らせて、その中の最も良かった TOTAL WALL CLOCK TIME を比較しました。こちらでも mkl が最も速かったのですが、差はそんなにないようです。

f:id:machakann:20180916203855j:plainf:id:machakann:20180921222256p:plain
The Computing Time of Caffeine Single Point Energy

Coumarin の Single Point Energy - B3LYP/6-311G(d)

インプットファイルはこちら

DFT 計算にはあまり BLAS を使わないのか、ほとんど差は出ませんでした。

f:id:machakann:20180916203859j:plainf:id:machakann:20180921222257p:plain
The Computing Time of Coumarin Single Point Energy

まとめ

mkl すごい。でも OpenBLAS が思った以上にいい勝負だった。

もしかすると、Single Point Energy 計算は題目として適切ではなかったかも。

おまけ : OpenBLAS を使う場合の注意

理由はよくわからないのですけど OpenBLAS がスレッドを分けると逆に遅くなるみたいです。なので、OpenBLAS を使う場合はスレッディングを無効にしたほうがよさそうです。

  • スレッディングを無効にビルドしたものをリンクした場合 (make USE_THREAD=0) は特に何もする必要はないです。

  • スレッディングが有効な OpenBLAS (make, make USE_THREAD=1) を使う場合には環境変数 OPENBLAS_NUM_THREADS でシングルスレッドで動作するようにすると大丈夫です。デフォルトで有効になっているのでこの場合が多いかもしれません。

export OPENBLAS_NUM_THREADS=1
  • OpenMP によるスレッディングが有効な OpenBLAS (make USE_OPENMP=1) を使う場合には環境変数 OMP_NUM_THREADS でシングルスレッドで動作するようにすると大丈夫です。
export OMP_NUM_THREADS=1

処理時間が以下のようにかなり変わります。

f:id:machakann:20180921222300p:plain
Alanine Single Point Energy CCSD(T)/6-311G (including OpenBLAS variations)

OpenBLAS:
OpenBLAS を make USE_THREAD=0 でビルド
GAMESS を /opt/gamess/rungms 00 4 alanine.inp と実行

OpenBLAS 1thread:
OpenBLAS を make USE_THREAD=1 でビルド
GAMESS を OPENBLAS_NUM_THREADS=1 /opt/gamess/rungms 00 4 alanine.inp と実行

OpenBLAS 4thread:
OpenBLAS を make USE_THREAD=1 でビルド
GAMESS を OPENBLAS_NUM_THREADS=4 /opt/gamess/rungms 00 4 alanine.inp と実行

OpenBLAS 1thread openmp:
OpenBLAS を make USE_OPENMP=1 でビルド
GAMESS を OMP_NUM_THREADS=1 /opt/gamess/rungms 00 4 alanine.inp と実行

OpenBLAS 4thread openmp:
OpenBLAS を make USE_OPENMP=1 でビルド
GAMESS を OMP_NUM_THREADS=4 /opt/gamess/rungms 00 4 alanine.inp と実行

GAMESS をビルドする (OpenBLAS 編)

ふと思い立って GAMESS をビルドして遊んだので記録を残そうと思います。基本的には GAMESS Installation Instructions for Linux に従いつつ、ビルドがコケたところを修正してまとめました。

参考 → mkl 編

環境

OS : Ubuntu 18.04 64bit
gcc : version 7.3.0
GAMESS : Feb 14, 2018 R1 Public Release
BLAS : OpenBlas v0.3.3

必要なソフトウェアをインストール

まず、ビルドのために fortran コンパイラと csh が必要なのでインストールします。

sudo apt-get install gfortran csh

c コンパイラも必要だったと思うので、gcc がインストールされていない場合はしましょう。gcc -v と打ってバージョン情報が出力されなければする必要があります。

sudo apt-get install build-essential

OpenBLAS のビルド

今回は OpenBLAS をビルドして使いました。v0.3.3 を使っていますが、新しいリリースがあればそっちを使うといいでしょう。試していませんが、apt-get でもインストールできるらしいです。面倒ならこっちでもいいとおもいます。

GAMESS にリンクして使う場合に限っていえば、スレッディング機能は無効にしたほうが無難だと思います。スレッディングを有効にしてビルドした場合でも環境変数で無効にできるので好きな方を選びましょう。

git clone https://github.com/xianyi/OpenBLAS.git
git checkout v0.3.3
cd OpenBLAS
make USE_THREAD=0
sudo make install PREFIX=/opt/OpenBLAS_NO_THREAD

GAMESS のビルド

GAMESS のソースファイル gamess-current.tar.gz は自分で入手しましょう。gamess-current.tar.gz~/Downloads にあり、ビルドは ~/gamess で行うものとしますが、違ったら適当に読み替えてください。

下の `whoami` はあなたのユーザーネームに置き換えてください。

cd ~/
tar xvf ~/Downloads/gamess-current.tar.gz
chown -R `whoami` gamess
chmod g-s gamess

OpenBLAS は公式にはサポートされていないので、configure の前に以下のどちらかのパッチを当てます。ここ を参考にして新しめの GAMESS に適用できるようにしました。

patch < ~/gamess_2018R1_openblas.diff
rm gamess_2018R1_openblas.diff

ここから対話的(!)な configure が始まります。

cd gamess
./config

This script asks a few questions, depending on your computer system, to set up compiler names, libraries, message passing libraries, and so forth.

You can quit at any time by pressing control-C, and then .

Please open a second window by logging into your target machine, in case this script asks you to 'type' a command to learn something about your system software situation. All such extra questions will use the word 'type' to indicate it is a command for the other window.

After the new window is open, please hit to go on.

<Enter> キーを押します。

GAMESS can compile on the following 32 bit or 64 bit machines:
axp64 - Alpha chip, native compiler, running Tru64 or Linux
cray-xt - Cray's massively parallel system, running CNL
cray-xc - Cray's XC40, with KNL nodes
hpux32 - HP PA-RISC chips (old models only), running HP-UX
hpux64 - HP Intel or PA-RISC chips, running HP-UX
ibm32 - IBM (old models only), running AIX
ibm64 - IBM, Power3 chip or newer, running AIX or Linux
ibm64-sp - IBM SP parallel system, running AIX
ibm-bg - IBM Blue Gene (Q model), these are 64 bit systems
linux32 - Linux (any 32 bit distribution), for x86 (old systems only)
linux64 - Linux (any 64 bit distribution), for x86_64 or ia64 chips,
using gfortran, ifort, or perhaps PGI compilers.
mac32 - Apple Mac, any chip, running OS X 10.4 or older
mac64 - Apple Mac, any chip, running OS X 10.5 or newer
sgi32 - Silicon Graphics Inc., MIPS chip only, running Irix
sgi64 - Silicon Graphics Inc., MIPS chip only, running Irix
sun32 - Sun ultraSPARC chips (old models only), running Solaris
sun64 - Sun ultraSPARC or Opteron chips, running Solaris
win32 - Windows 32-bit (Windows XP, Vista, 7, Compute Cluster, HPC Edition)
win64 - Windows 64-bit (Windows XP, Vista, 7, Compute Cluster, HPC Edition)
winazure - Windows Azure Cloud Platform running Windows 64-bit
type 'uname -a' to partially clarify your computer's flavor.
please enter your target machine name:

linux64 を入力して <Enter> を押します。

Where is the GAMESS software on your system?
A typical response might be /u1/mike/gamess,
most probably the correct answer is /opt/gamess

GAMESS directory? [/opt/gamess]

<Enter> キーを押します。

Please provide the name of the build locaation.
This may be the same location as the GAMESS directory.

GAMESS build directory? [/opt/gamess]

<Enter> キーを押します。

Please provide a version number for the GAMESS executable.
This will be used as the middle part of the binary's name,
for example: gamess.00.x

Version? [00]

<Enter> キーを押します。

Linux offers many choices for FORTRAN compilers, including the GNU
compiler suite's free compiler 'gfortran', usually included in
any Linux distribution. If gfortran is not installed, it can be
installed from your distribution media.

To check on installed GNU compilers, for RedHat/SUSE style Linux,
type 'rpm -aq | grep gcc' for both languages,
and for Debian/Ubuntu style Linux, it takes two commands
type 'dpkg -l | grep gcc'
type 'dpkg -l | grep gfortran'

There are also commercial compilers, namely Intel's 'ifort', and
Portland Group's 'pgfortran', and Pathscale's 'pathf90'.
The last two are not common, and aren't as well tested.

type 'which gfortran' to look for GNU's gfortran (a good choice),
type 'which ifort' to look for Intel's compiler (a good choice),
type 'which pgfortran' to look for Portland Group's compiler,
type 'which pathf90' to look for Pathscale's compiler.
Please enter your choice of FORTRAN:

gfortran と入力し、<Enter> キーを押します。

gfortran is very robust, so this is a wise choice.

Please type 'gfortran -dumpversion' or else 'gfortran -v' to
detect the version number of your gfortran.
This reply should be a string with at least two decimal points,
such as 4.1.2 or 4.6.1, or maybe even hyphens like 4.4.2-12.
The reply may be labeled as a 'gcc' version,
but it is really your gfortran version.

Please enter only the first decimal place, such as 4.6 or 4.8:

gfortran のバージョンを入力するところです。現在 (Sep. 2018) apt で降ってくる gfortran のバージョンは 7.3 だと思うのですが、残念ながら素直に 7.3 と入力するとエラーになります。その場合は、7.2 と入力して <Enter> しましょう。たぶん大丈夫です。GAMESS がアップデートされたらこの問題もなくなると思います。

hit to continue to the math library setup.

<Enter> キーを押します。

Linux distributions do not include a standard math library.

There are several reasonable add-on library choices,
MKL from Intel for 32 or 64 bit Linux (very fast)
ACML from AMD for 32 or 64 bit Linux (free)
ATLAS from www.rpmfind.net for 32 or 64 bit Linux (free)
PGI BLAS from Portland Group for 32 or 64 bit Linux
and one very unreasonable option, namely 'none', which will use
some slow FORTRAN routines supplied with GAMESS. Choosing 'none'
will run MP2 jobs 2x slower, or CCSD(T) jobs 5x slower.

Some typical places (but not the only ones) to find math libraries are
Type 'ls /opt/intel/mkl' to look for MKL
Type 'ls /opt/intel/Compiler/mkl' to look for MKL
Type 'ls /opt/intel/composerxe/mkl' to look for MKL
Type 'echo '$MKLROOT'"' to look for MKL"
Type 'ls -d /opt/acml' to look for ACML
Type 'ls -d /usr/local/acml
' to look for ACML
Type 'ls /usr/lib64/atlas' to look for Atlas
Type 'ls /opt/pgi/linux86-64//lib/ to look for libblas.a from PGI
Type 'ls /opt/pgi/osx86-64//lib/ to look for libblas.a from PGI

Enter your choice of 'mkl' or 'atlas' or 'acml' or 'pgiblas' or 'openblas' or 'none':

openblas と入力して <Enter> を押します。

Enter full path to OpenBLAS libraries (without 'lib' subdirectory):

/opt/OpenBLAS_NO_THREAD と入力し <Enter> を押します。

please hit to compile the GAMESS source code activator

<Enter> を押します。

please hit to set up your network for Linux clusters.

<Enter> を押します。

If you have a slow network, like Gigabit Ethernet (GE), or
if you have so few nodes you won't run extensively in parallel, or
if you have no MPI library installed, or
if you want a fail-safe compile/link and easy execution,
choose 'sockets'
to use good old reliable standard TCP/IP networking.

If you have an expensive but fast network like Infiniband (IB), and
if you have an MPI library correctly installed,
choose 'mpi'.

communication library ('sockets' or 'mpi')?

sockets と入力し <Enter> を押します。

64 bit Linux builds can attach a special LIBCCHEM code for fast
MP2 and CCSD(T) runs. The LIBCCHEM code can utilize nVIDIA GPUs,
through the CUDA libraries, if GPUs are available.
Usage of LIBCCHEM requires installation of HDF5 I/O software as well.
GAMESS+LIBCCHEM binaries are unable to run most of GAMESS computations,
and are a bit harder to create due to the additional CUDA/HDF5 software.
Therefore, the first time you run 'config', the best answer is 'no'!
If you decide to try LIBCCHEM later, just run this 'config' again.

Do you want to try LIBCCHEM? (yes/no):

no と入力して <Enter> を押します。これで configure の終了です。

GAMESS 独自の分散コンピューティング用ライブラリ (?) ddi をビルドします。

cd ddi
./compddi >& compddi.log
mv ddikick.x ..
cd ..

うまく行っていれば、compddi.log の最後の方に "DDI compilation ended successfully." という文があると思います。

いよいよ GAMESS をビルド (&リンク) します。少し時間がかかると思います。

./compall >& compall.log
./lked >& lked.log

最後に rungms スクリプトを編集します。63行目あたりに以下のような箇所があるので、

set TARGET=sockets
set SCR=/scr/$USER
set USERSCR=/u1/$USER/scr
set GMSPATH=/u1/mike/gamess

次のように編集します。

set TARGET=sockets
set SCR=/tmp
set USERSCR=/tmp
set GMSPATH=$HOME/gamess

SCR および、USERSCR は計算のための一時ファイルを置く場所らしいです。編集する行の上のコメントに簡単な説明があります。好きに決めて問題ないと思います。(/tmp はちょっと乱暴かもしれない…)

GMSPATH はビルドした gamess.00.x があるパスなので、ひとまずテストのために $HOME/gamess にします。

GAMESS のテスト

ビルドした GAMESS をテストします。

./runall 00

00 は GAMESS のバイナリを指定するための引数で gamess.00.x を使うという意味です。省略したら 00 になると思います。テストが終わったら、exam01.log から exam47.log までの47のファイルが出力されます。確認するためには

tests/standard/checktst

を実行して All 47 test results are correct! と表示されれば OK です!異常終了しているファイルがあれば内容をよく確認しましょう。

GAMESS のインストール

インストール先は /opt/gamess とします。GAMESS は Filesystem Hierarchy Standard に従っているソフトウェアではないようなので /usr/local 以下は適当なインストール先ではなさそうです。

まず、rungms ファイルを編集して GMSPATH を再度変更します。

set GMSPATH=/opt/gamess

ディレクトリごと移動して所有者を変更して終わりです。

cd ~/
sudo mv gamess /opt
cd /opt
chown -R root:root gamess

おまけ

.bashrc あたりで alias とか作ったら使いやすいと思います。

alias rungms=/opt/gamess/rungms

さらにキャッシュをクリアしてから実行してくれるようなスクリプト~/.local/bin/ に置いて使っています。

alias gamess=~/.local/bin/gamess.sh

GAMESS をビルドする (mkl 編)

ふと思い立って GAMESS をビルドして遊んだので記録を残そうと思います。基本的には GAMESS Installation Instructions for Linux に従いつつ、ビルドがコケたところを修正してまとめました。

参考 → OpenBLAS 編

環境

OS : Ubuntu 18.04 64bit
gcc : version 7.3.0
GAMESS : Feb 14, 2018 R1 Public Release
BLAS : mkl (intel-mkl-2018.3-051)

必要なソフトウェアをインストール

まず、ビルドのために fortran コンパイラと csh が必要なのでインストールします。

sudo apt-get install gfortran csh

c コンパイラも必要だったと思うので、gcc がインストールされていない場合はしましょう。gcc -v と打ってバージョン情報が出力されなければする必要があります。

sudo apt-get install build-essential

intel-mkl のインストール

intel-mkl パッケージをインストールします。intel による解説 に従って intel-mkl パッケージをインストールします。バージョンがいくつかありますが、よくわからないので一番新しい (2018/9月現在) ものを選びました。

wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB
apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB
rm GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB

sudo apt-get update

sudo apt-get intel-mkl-2018.3-051

/opt/intel 以下にインストールされるようです。

GAMESS のビルド

GAMESS のソースファイル gamess-current.tar.gz は自分で入手しましょう。gamess-current.tar.gz~/Downloads にあり、ビルドは ~/gamess で行うものとしますが、違ったら適当に読み替えてください。

下の `whoami` はあなたのユーザーネームに置き換えてください。

cd ~/
tar xvf ~/Downloads/gamess-current.tar.gz
chown -R `whoami` gamess
chmod g-s gamess

cd gamess
./config

ここから対話的(!)な configure が始まります。

This script asks a few questions, depending on your computer system, to set up compiler names, libraries, message passing libraries, and so forth.

You can quit at any time by pressing control-C, and then .

Please open a second window by logging into your target machine, in case this script asks you to 'type' a command to learn something about your system software situation. All such extra questions will use the word 'type' to indicate it is a command for the other window.

After the new window is open, please hit to go on.

<Enter> キーを押します。

GAMESS can compile on the following 32 bit or 64 bit machines:
axp64 - Alpha chip, native compiler, running Tru64 or Linux
cray-xt - Cray's massively parallel system, running CNL
cray-xc - Cray's XC40, with KNL nodes
hpux32 - HP PA-RISC chips (old models only), running HP-UX
hpux64 - HP Intel or PA-RISC chips, running HP-UX
ibm32 - IBM (old models only), running AIX
ibm64 - IBM, Power3 chip or newer, running AIX or Linux
ibm64-sp - IBM SP parallel system, running AIX
ibm-bg - IBM Blue Gene (Q model), these are 64 bit systems
linux32 - Linux (any 32 bit distribution), for x86 (old systems only)
linux64 - Linux (any 64 bit distribution), for x86_64 or ia64 chips,
using gfortran, ifort, or perhaps PGI compilers.
mac32 - Apple Mac, any chip, running OS X 10.4 or older
mac64 - Apple Mac, any chip, running OS X 10.5 or newer
sgi32 - Silicon Graphics Inc., MIPS chip only, running Irix
sgi64 - Silicon Graphics Inc., MIPS chip only, running Irix
sun32 - Sun ultraSPARC chips (old models only), running Solaris
sun64 - Sun ultraSPARC or Opteron chips, running Solaris
win32 - Windows 32-bit (Windows XP, Vista, 7, Compute Cluster, HPC Edition)
win64 - Windows 64-bit (Windows XP, Vista, 7, Compute Cluster, HPC Edition)
winazure - Windows Azure Cloud Platform running Windows 64-bit
type 'uname -a' to partially clarify your computer's flavor.
please enter your target machine name:

linux64 を入力して <Enter> を押します。

Where is the GAMESS software on your system?
A typical response might be /u1/mike/gamess,
most probably the correct answer is /opt/gamess

GAMESS directory? [/opt/gamess]

<Enter> キーを押します。

Please provide the name of the build locaation.
This may be the same location as the GAMESS directory.

GAMESS build directory? [/opt/gamess]

<Enter> キーを押します。

Please provide a version number for the GAMESS executable.
This will be used as the middle part of the binary's name,
for example: gamess.00.x

Version? [00]

<Enter> キーを押します。

Linux offers many choices for FORTRAN compilers, including the GNU
compiler suite's free compiler 'gfortran', usually included in
any Linux distribution. If gfortran is not installed, it can be
installed from your distribution media.

To check on installed GNU compilers, for RedHat/SUSE style Linux,
type 'rpm -aq | grep gcc' for both languages,
and for Debian/Ubuntu style Linux, it takes two commands
type 'dpkg -l | grep gcc'
type 'dpkg -l | grep gfortran'

There are also commercial compilers, namely Intel's 'ifort', and
Portland Group's 'pgfortran', and Pathscale's 'pathf90'.
The last two are not common, and aren't as well tested.

type 'which gfortran' to look for GNU's gfortran (a good choice),
type 'which ifort' to look for Intel's compiler (a good choice),
type 'which pgfortran' to look for Portland Group's compiler,
type 'which pathf90' to look for Pathscale's compiler.
Please enter your choice of FORTRAN:

gfortran と入力し、<Enter> キーを押します。

gfortran is very robust, so this is a wise choice.

Please type 'gfortran -dumpversion' or else 'gfortran -v' to
detect the version number of your gfortran.
This reply should be a string with at least two decimal points,
such as 4.1.2 or 4.6.1, or maybe even hyphens like 4.4.2-12.
The reply may be labeled as a 'gcc' version,
but it is really your gfortran version.

Please enter only the first decimal place, such as 4.6 or 4.8:

gfortran のバージョンを入力するところです。現在 (Sep. 2018) apt で降ってくる gfortran のバージョンは 7.3 だと思うのですが、残念ながら素直に 7.3 と入力するとエラーになります。その場合は、7.2 と入力して <Enter> しましょう。たぶん大丈夫です。GAMESS がアップデートされたらこの問題もなくなると思います。

hit to continue to the math library setup.

<Enter> キーを押します。

Linux distributions do not include a standard math library.

There are several reasonable add-on library choices,
MKL from Intel for 32 or 64 bit Linux (very fast)
ACML from AMD for 32 or 64 bit Linux (free)
ATLAS from www.rpmfind.net for 32 or 64 bit Linux (free)
PGI BLAS from Portland Group for 32 or 64 bit Linux
and one very unreasonable option, namely 'none', which will use
some slow FORTRAN routines supplied with GAMESS. Choosing 'none'
will run MP2 jobs 2x slower, or CCSD(T) jobs 5x slower.

Some typical places (but not the only ones) to find math libraries are
Type 'ls /opt/intel/mkl' to look for MKL
Type 'ls /opt/intel/Compiler/mkl' to look for MKL
Type 'ls /opt/intel/composerxe/mkl' to look for MKL
Type 'echo '$MKLROOT'"' to look for MKL"
Type 'ls -d /opt/acml' to look for ACML
Type 'ls -d /usr/local/acml
' to look for ACML
Type 'ls /usr/lib64/atlas' to look for Atlas
Type 'ls /opt/pgi/linux86-64//lib/ to look for libblas.a from PGI
Type 'ls /opt/pgi/osx86-64//lib/ to look for libblas.a from PGI

Enter your choice of 'mkl' or 'atlas' or 'acml' or 'pgiblas' or 'none':

mkl と入力して <Enter> を押します。

The exact MKL libraries needed depend on its version number.
First, where is your MKL software installed? For example
/opt/intel/mkl -or-
/opt/intel/Compiler/mkl -or-
/opt/intel/composerxe/mkl -or-
/your/sites/nonstandard/path/mkl

Found: Nothing.

Don't enter anything past the mkl subdirectory pathname.
MKL pathname?

/opt/intel/mkl と入力し <Enter> を押します。

Second, it is possible to have multiple version of MKL
installed, but often there is only one version installed.
Your system seems to have the following version(s):

benchmarks bin examples include interfaces lib tools

a) If the above output contains one or more version number,
enter the specific version you prefer, giving all decimals.
b) If the above output contains paths like 'bin' and 'lib',
enter the word 'proceed' next.
MKL version (or 'proceed')?

proceed と入力し <Enter> を押します。

please hit to compile the GAMESS source code activator

<Enter> を押します。

please hit to set up your network for Linux clusters.

<Enter> を押します。

If you have a slow network, like Gigabit Ethernet (GE), or
if you have so few nodes you won't run extensively in parallel, or
if you have no MPI library installed, or
if you want a fail-safe compile/link and easy execution,
choose 'sockets'
to use good old reliable standard TCP/IP networking.

If you have an expensive but fast network like Infiniband (IB), and
if you have an MPI library correctly installed,
choose 'mpi'.

communication library ('sockets' or 'mpi')?

sockets と入力し <Enter> を押します。

64 bit Linux builds can attach a special LIBCCHEM code for fast
MP2 and CCSD(T) runs. The LIBCCHEM code can utilize nVIDIA GPUs,
through the CUDA libraries, if GPUs are available.
Usage of LIBCCHEM requires installation of HDF5 I/O software as well.
GAMESS+LIBCCHEM binaries are unable to run most of GAMESS computations,
and are a bit harder to create due to the additional CUDA/HDF5 software.
Therefore, the first time you run 'config', the best answer is 'no'!
If you decide to try LIBCCHEM later, just run this 'config' again.

Do you want to try LIBCCHEM? (yes/no):

no と入力して <Enter> を押します。これで configure の終了です。

GAMESS 独自の分散コンピューティング用ライブラリ (?) ddi をビルドします。

cd ddi
./compddi >& compddi.log
mv ddikick.x ..
cd ..

うまく行っていれば、compddi.log の最後の方に "DDI compilation ended successfully." という文があると思います。

いよいよ GAMESS をビルド (&リンク) しますが、私の環境では少し修正しないとリンクで失敗しました。パッチ にしています。

patch < ~/gamess_2018R1_mkl.diff
rm gamess_2018R1_mkl.diff

ビルドには少し時間がかかると思います。

./compall >& compall.log
./lked >& lked.log

最後に rungms スクリプトを編集します。63行目あたりに以下のような箇所があるので、

set TARGET=sockets
set SCR=/scr/$USER
set USERSCR=/u1/$USER/scr
set GMSPATH=/u1/mike/gamess

次のように編集します。

set TARGET=sockets
set SCR=/tmp
set USERSCR=/tmp
set GMSPATH=$HOME/gamess

SCR および、USERSCR は計算のための一時ファイルを置く場所らしいです。編集する行の上のコメントに簡単な説明があります。好きに決めて問題ないと思います。(/tmp はちょっと乱暴かもしれない…)

GMSPATH はビルドした gamess.00.x があるパスなので、ひとまずテストのために $HOME/gamess にします。

GAMESS のテスト

ビルドした GAMESS をテストします。

./runall 00

00 は GAMESS のバイナリを指定するための引数で gamess.00.x を使うという意味です。省略したら 00 になると思います。テストが終わったら、exam01.log から exam47.log までの47のファイルが出力されます。確認するためには

tests/standard/checktst

を実行して All 47 test results are correct! と表示されれば OK です!異常終了しているファイルがあれば内容をよく確認しましょう。

GAMESS のインストール

インストール先は /opt/gamess とします。GAMESS は Filesystem Hierarchy Standard に従っているソフトウェアではないようなので /usr/local 以下は適当なインストール先ではなさそうです。

まず、rungms ファイルを編集して GMSPATH を再度変更します。

set GMSPATH=/opt/gamess

ディレクトリごと移動して所有者を変更して終わりです。

cd ~/
sudo mv gamess /opt
cd /opt
chown -R root:root gamess

おまけ

.bashrc あたりで alias とか作ったら使いやすいと思います。

alias rungms=/opt/gamess/rungms

さらにキャッシュをクリアしてから実行してくれるようなスクリプト~/.local/bin/ に置いて使っています。

alias gamess=~/.local/bin/gamess.sh