本当は怖いHPC

HPC屋の趣味&実益ブログ

mpirunとmpiexecの違いは何か

MPIプログラムを起動する方法として,mpirunmpiexecがあります.プログラムを普通に起動するだけなら,どちらのコマンドでも困ることはありません.実行するノードとプロセス数の指定をする程度なら,どの実装のどちらのコマンドを使っても大差ないからです.

初期のMPI標準(MPI-1)には,プログラムの起動方法は言及されていませんでした.よって,それぞれのMPI実装はmpirunと呼ばれるコマンドを実装しましたが,コマンドラインオプションはそれぞれ異なるものでした.

これは不便だということで、MPI-2においてmpiexecが標準として定められました.現在の標準である MPI-3.1 では,「8.8 Portable MPI Process Startup」でmpiexecコマンドが述べられています.

標準なのだから黙ってmpiexecを使えばいいのですが,残念ながら話はそこまで単純ではありません.現実には,mpiexecに定められているのは最大公約数的なオプションだけで,詳細は実装に任されています.

オプション 意味
-n プロセス数
-host MPIプログラムを実行するホストが指定されたファイル(書式は実装依存)
-arch アーキテクチャ名.よくわからん
-wdir プロセスが実行される実行ディレクトリ名
-file 実行に関する追加情報が書かれたファイルを指定.中身は実装依存(なんじゃそりゃ)
-sort MPI_COMM_SPAWNなどが作れるプロセス数を指定.詳細省略

標準なので仕方ないのですが,これではいかにも物足りません.

現実的に重要なのは,プロセスのリソースへのマッピングバインディング,それから環境変数の指定です.MPI実装の事実上の二強である Open MPI と Mpich では,--map-by--bind-to-x-genvなどのオプションが実装されていますが,それぞれ詳細は異なります.これらについてのまとめは非常に少ないので,時間を見つけてまとめてみたいと思います.

余談だが,世の中の殆どのMPI実装は Open MPIか Mpichの派生で、mpichの派生としては mvapich, Intel MPI,またOpen MPIの派生としてはFujitsu MPIなどがあります.この2つのmpiexecの文法を身につければ怖くないと言えるでしょう.

MPI並列プログラミング

MPI並列プログラミング

関数プログラミング入門・一人読書会 (4)

関数プログラミング入門」の練習問題をやっていきます

今回は1.5.1〜1.5.2

1.5.1

フィボナッチ数を計算する関数fibを定義する

fib :: Integer -> Integer
fib n
  | n <  0 = error "fib: n must be >= 0"
  | n == 0 = 0
  | n == 1 = 1
  | otherwise = fib (n - 1) + fib (n - 2)

main :: IO()
main = putStrLn $ show $ (fib 20) == 6765

1.5.2

整数の絶対値を返す関数absを定義せよ

abs' :: Integer -> Integer
abs' n
  | n < 0 = -n
  | otherwise = n

main :: IO()
main = do
  putStrLn $ show $ (abs'   0) ==  0
  putStrLn $ show $ (abs'  20) == 20
  putStrLn $ show $ (abs' (-20)) == 20

関数プログラミング入門 ―Haskellで学ぶ原理と技法―

関数プログラミング入門 ―Haskellで学ぶ原理と技法―

関数プログラミング入門・一人読書会 (3)

関数プログラミング入門」の練習問題をやっていきます

関数プログラミング入門 ―Haskellで学ぶ原理と技法―

関数プログラミング入門 ―Haskellで学ぶ原理と技法―

今回は1.4.1〜1.4.7

1.4.1

hの型は,

h :: Integer -> Integer -> Integer

fとgの型は f :: Integer -> Integerg :: Integer -> (Integer -> Integer) なので,(・)の定義に照らすとf・gは型が整合しない.これを考慮すると,正しいのは

h x = f・(g x)

である

1.4.2

deltaをカリー化した型は

delta :: Float -> Float -> Float -> Float

1.4.3

log' :: Float -> (Float -> Float)

1.4.4

関数の名前をIntegとすると,まず積分される対象の関数の型は Float -> Float.よって,

Integ :: (Float -> Float) -> Float -> Float -> Float

1.4.5

前者については,与えられた関数に0を適用して,その数にsquareを適用するような関数ZeroSquareは,

let ZeroSquare f = square ( f 0 )
ZeroSquare :: (Integer -> Integer) -> Integer

後者は,本文中の twiceが例である

1.4.6

-xはxの符号反転を示すので,3つ目は偽.また,+×は交換法則が成り立つ.よって2つが真.

1.4.7

uncurry f (x, y) = f x y
curry (uncurry f) x y
 = curry ((x', y') -> f x' y') x y
 = ((x', y') -> f x' y') (x, y)
 = f x y

uncurry (curry f) (x, y)
 = uncurry (x -> y -> f (x, y)) (x, y)
 = (x -> y -> f (x, y)) x y
 = f (x, y)
【広告】