構造解析ことはじめ/03 プログラムのインストール CNS

CNSのインストール  

リリース情報など  

CNS 1.3/1.21のインストール -- Vine4 Vine5 CentOS5  

注意点  

CentOS 6.4でld: cannot find -lmエラーが出る -- 2013-07-13
CentOS 6.4(64bit)でインストールを試したところ以下のエラーが出ました。
...(省略)
make default
ifort -o PSmapx -O -w PSmapx.f -static
ld: cannot find -lm
make[4]: *** [PSmapx] エラー 1
make[3]: *** [utils] エラー 2
make[2]: *** [compile-utils] エラー 2
make[1]: *** [utils] エラー 2
...(省略)
これはlibm.a(mathのスタティックライブラリ)が不足している場合に起こるようです。この場合glibc-staticをインストールします。
# yum install glibc-static
これで問題は解決されるようです。

インストール  

インストールは1.1に比べて非常に簡単になりました。
rootでの作業になりますが、cns_solve_envがcsh用スクリプトなのでtcsh上で行います。

  1. /usr/local/以下にcns_solve_1.21_all.tar.gzを展開します。
    • マルチコア、マルチプロセッサならcns_solve_1.21_all-mp.tar.gzを試してみるのもいいかも
  2. /usr/local/cns_solve_1.21/cns_solve_envを修正します
  3. コンパイルします

以下は実際のコマンドです。コンパイルにIntel Compilerを検索しますのでifortvars.cshをあらかじめ読み込んでおいてください。CNSはIntel Compilerで最適化されるらしく、相当速くなりますのでIntel Compilerの利用をおすすめします。

/usr/local/cns_solve_1.21にファイルを展開  

# tcsh
# cd /usr/local
# tar zxvf cns_solve_1.21_all-mp.tar.gz
# cd /usr/local/cns_solve_1.21

cns_solve_envの編集  

# vi cns_solve_env  <-- 18行目のCNSの場所を指定します

cns_solve_envを編集。通常は、

18             setenv CNS_SOLVE '_CNSsolve_location_'

_CNSsolve_location_を環境に合わせて修正します。

18             setenv CNS_SOLVE '/usr/local/cns_solve_1.21'

コンパイル  

無難なインストール -- 非OpenMP;シングルスレッド版
CNS 1.2の時はIntel Compiler ver.9でビルドしましたが、今回(1.21)はver.10.1および11.0を使ってみました。ここに示してある方法ではマルチスレッド対応版はビルドされません。下のOpenMP有効化を参照して下さい。
なお、Intel Compiler ver.11ではsourceのコマンドが変わっています。手元の環境に合わせてsourceコマンドを実行してください。
# tcsh                                                        (tcshで作業)
# source /opt/intel/cc/10.1.015/bin/iccvars.csh               (Ver.10 C++環境設定)
# source /opt/intel/fc/10.1.015/bin/ifortvars.csh             (Ver.10 Fortran環境設定)
# source /opt/intel/Compiler/11.0/074/bin/iccvars.csh ia32    (Ver.11 C++環境設定)
# source /opt/intel/Compiler/11.0/074/bin/ifortvars.csh ia32  (Var.11 Fortran環境設定)
# source cns_solve_env
# make install
これで終わりです。
OpenMP有効化 -- マルチスレッド版(使用時に注意事項あり)
Intel Compiler 11.0以上推奨
コンパイルするときにOpenMPを有効にしないと並列化機能が有効になりません。上のやり方でコンパイルしたものでは処理時間が1.2と変わらなかったのでちょっと攻めてみました。
同じ条件で非OpenMPのものと計算時間で比べたとき、前者は20分、後者は15分でした(Pentium dual-core 1.8GHzのとき)。4コアで実行した場合は計算時間が約半分になるようです。
Intel Compiler ver.10でもコンパイルできますがver.11のほうがOpemMP動作が安定しているような気がしました。
# tcsh
# source /opt/intel/cc/10.1.015/bin/iccvars.csh          (Ver.10 C++)
# source /opt/intel/fc/10.1.015/bin/ifortvars.csh        (Ver.10 Fortran)
# source /opt/intel/Compiler/11.0/074/bin/iccvars.csh    (Var.11 C++)
# source /opt/intel/Compiler/11.0/074/bin/ifortvars.csh  (Var.11 Fortran)
# source cns_solve_env
# setenv EXT_F77FLAGS "-openmp -ip" <-- FORTRAN最適化オプション (Ver.10, 11共通)
# setenv EXT_LDFLAGS "-openmp -ip"  <-- リンカオプション        (Ver.10, 11共通)
# make install
これでビルドできるはずです。
しかし、ver.10でビルドしたOpenMP版は実行する際に少し設定がいります。スタックサイズがディフォルトでは小さいようなので(小さいとSegmentation Faultが出ます)、増やしてからCNSを実行します。ただ、私の場合は750残基x3で試したからかもしれません。
Intel Compiler Ver.11でコンパイルしたCNSでは同じ条件でも最後まで処理できましたのでこの設定は必要ないのかもしれません。基本的にはVer.11でコンパイルしたCNSをスタックサイズの設定なしで問題なく使用できるようですが、処理の内容によってはクラッシュすることがありました。その際はスタックサイズの調整を行ってみてください(私の環境では200残基x6@2.7Åのanneal.inpで発生しました)。
スタックサイズを増やしてもSegmentation Faultを起こす場合は、無難なインストールで使ってください。スタックサイズをunlimitedにすると気にせず使えそうです。
% limit stacksize unlimited
% cns < refine.inp | tee refine.log

使用準備  

インストールが終了したら使用するユーザーの.cshrcファイルに以下の行を追加しておきます。

# for CNS
source /usr/local/cns_solve_1.21/cns_solve_env

並列化版(OpenMP対応版) CNSを使ってみる  

通常版と並列化版の見分けかた  

OpenMPオプションを付けた場合と付けなかった場合はCNSを実行した場合にわかります。CNSを実行したときの表示で、

% cns
通常版(並列処理なし)
         ============================================================
          Running on machine: bix07 (Linux,32-bit)
          Program started by: dobuo
          Program started at: 15:49:17 on 22-Oct-2008
         ============================================================
並列化版
         ============================================================
          Running on machine: bix07 (Linux,32-bit)
                              with  4 threads
          Program started by: dobuo
          Program started at: 15:49:39 on 22-Oct-2008
         ============================================================

ホスト数の次の行にwithでスレッド数が表示されているのがわかります。何らかの理由でスレッド数を制限したい場合は環境変数OMP_NUM_THREADSに最大のスレッド数を指定します。

% setenv OMP_NUM_THREADS 2

するとwithの値が変わります。

通常版と並列化版の計算時間の差  

参考までに。750残基x3で分解能3.6A、refine.inpを実行しました。

CPU通常版並列化版(スレッド数)
Pentium Dual-Core 1.8GHz20分15分(2)
Core2 Quad 2.4GHz15分10分(4)
Core i7 940 2.93GHz7分(8)

4スレッドでも思ったほどの高速化はありませんでしたね。ただ、Composite Omit Mapの場合はかかる時間が長いのでメリットが大きいかもしれません(概算になりますが、CPU時間と実際にかかった時間を比べると1/3程度になってました。CPU時間が5時間、実際にかかった時間は1.5時間)。計算の実行途中でtopコマンドを見てみるとcnsプロセスが複数または100%を超えているのがわかります。

並列化版の難しさ  

Intel Compiler 11だとスタックサイズの設定等をしなくても安定しています。Intel Compiler 10でビルドしたものを使っていて、よく落ちる方は試してみては?

Segmentation faultする  

スタックサイズの上限を増やしておかないとこんな感じでSegmentation faultします。

OMP abort: Unable to set worker thread stack size to 8389632 bytes
Try reducing KMP_STACKSIZE or increasing the shell stack limit.

この時は、limitコマンドでスタックサイズを増やしてみてください。

スタックサイズを増やしたのに停止する  

しかし、スタックサイズを32MBぐらいにしても(ってむちゃくちゃなスタックサイズですが)Segmentation faultで停止することがあります。

forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC        Routine            Line        Source             
.                  00110416  Unknown               Unknown  Unknown
cns                08766713  Unknown               Unknown  Unknown
libpthread.so.0    0067650B  Unknown               Unknown  Unknown
libc.so.6          005B7B2E  Unknown               Unknown  Unknown

落ちないときもあるので謎なのですが・・・
ちょっと調べてみたところ、原因が同じかどうかはわかりませんが、CCP4 WikiのCNSに以下の記述がありました。

It was reported that due to an operating system bug in Mac OSX 10.5.x, the program may crash with

forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC        Routine            Line        Source 
cns_solve          003548DF  Unknown               Unknown  Unknown
cns_solve          00339FBB  Unknown               Unknown  Unknown
cns_solve          000F62EC  Unknown               Unknown  Unknown
Stack trace terminated abnormally.

Imageが違いますが、エラー番号(174)が同じなので原因は同じかもしれません。それとmay crashなのでうまく走ることもあるというニュアンスなら、たしかに最後まで走ったり走らなかったりします。

This may occur if you are running the program with input redirection, but without output redirection, i.e.,

cns < test.inp

と。私は通常cns < test.inp | tee test.logのようにパイプを通してteeに流してますが、リダイレクトしているわけではないので同じ現象かもしれません。とりあえず、

and the input file contains one ore more blank lines.
As a possible remedy, try:

cns < test.inp > test.out

と書いてあるので、そのようにしてみるとよいのかも。