- 投稿日:2021-02-27T15:08:53+09:00
SourcetreeからGithubにSSH接続する
はじめに
本記事は自分のための備忘録です。
続するための制定源の情報のみしか記載していません。環境
mac OS BigSur 11.2.1
Sourcetree 4.1.0$ cd ~/.ssh $ ssh-keygen -t rsaGithubでやること
公開鍵を登録
https://github.com/
プロフィールアイコンをクリックしてsetting > SSH and GPG
と進み、SSH keysのNew SSH keyボタンをクリック。
上記で生成したid_rsa.pubの中身をコピペして登録。Sourcetreeでやること
環境設定を開いてアカウントタブを開く。
追加...ボタンをクリックしてウインドウを開く。ホスト:Github
認証タイプ:SSH
アカウントを接続ボタンを押下してGithubアカウントで認証
SSHキー:上記で生成した公開鍵が表示されていることを確認
保存ボタンを押下して設定を保存する。
ハマった点
接続テストを行うことで、known_hostsにGithubが登録され、URLからクローンできるようになった。
$ ssh -T git@github.com
- 投稿日:2021-02-27T14:02:13+09:00
超絶初心者がMacでEclipseを動かすまで
自分が通っていた職業訓練校ではEclipseを使ってコードを書いていたので、家でも同じようにしよう!と思ったのですが、訓練校で使っていたのは Windows、家のはMacで、微妙に違う!
しかも自分はMacを持ってるにも関わらずMac初心者(今使ってるノートパソコンが初Mac)なので、今後同じ事をする必要がある時用の覚え書きに。注:自分が後で見返す用にスマホ撮影した写真を載せてますが、自分用なので汚いです。
とりあえずEclipseを日本語で使いたいので、
https://mergedoc.osdn.jp/
から日本語化のプラグインを纏めてインストールします。
Windowsでした時は7-zipとかいうのもダウンロードして、それを使って解凍していましたが、Macでは必要ないみたいです。らくちん。
インストール完了したらとりあえず開いてみます。
ディレクトリの選択が出てきますが、もう何か選択されているのでそのまま起動します。
おおお!できました。
次は動かしてみる予定です。
何を作ろうかなー。
- 投稿日:2021-02-27T10:58:44+09:00
google-java-formatをVSCode・macOS環境で利用する
対象とする読者
VSCode・macOS環境でのjava開発にてGoogle Java Styleに自動整形するフォーマッタ(google-java-format)を適用させたい方
環境
macOS Catalina (version: 10.15.7)
VSCode for macOS (version: 1.53.2)設定法
- ターミナルにてHomebrewでgoogle-java-formatをインストール
brew install google-java-format
VSCodeにて
setting.json
に以下の要素を追加1{ "emeraldwalk.runonsave": { "commands": [ { "match": "\\.java$", "cmd": "google-java-format --replace ${file}" }, ], }, }参考
- 投稿日:2021-02-27T03:25:44+09:00
macOSで並列処理をするためのOpenMP, OpenMPIの環境構築
2021/02/27更新
はじめに
初投稿です。
自分がmacにOpenMPとOpenMPIを導入する際かなり混乱したため、自分のような初心者でもわかるように書きました。参考になれば幸いです。並列処理
プログラムは基本1つの実行に対して1つのコアかつ1つのスレッドしか使用しません。
そのためPC内の他のコアは常に暇しており、また計算以外の処理中などは使用しているコア自体も手持ち無沙汰になっています。
簡単なプログラムであれば問題ありませんが、プログラムによっては計算時間が非常にかかるため、暇している他のコアに仕事を振ったり、使用しているコアにもスレッドを分けて複数の仕事を与えたいところです。
そこで並列処理を行います。プログラム内のデータを各スレッドや各コアに分散させ、計算が終わったところで各スレッドや各コアからデータを収集します。
今回導入するOpenMP、OpenMPIはそれぞれスレッド、コアを並列化することが出来ます。OpenMPとOpenMPI
OpenMPはスレッド並列化を行うAPIです。1つのCPUが1つのコアしか持っていなくても、複数の処理を同時に行うことができます。
OpenMPIはMPI(Message Passing Interface)の一種で、プロセス自体を並列化するライブラリでありOpenMPとは全くの別物です。1つの命令を1つのコアではなく複数のコア(プロセス)を用いて処理します。これらを同時に使用することで、各コアがそれぞれ複数の処理を同時に行うことができるようになり、計算速度が上がります。
環境
macOS Sierra 10.12.6
macOS Mojave 10.14.6
macOS Catalina 10.15.7基本的にはfortranではなくC,C++を想定しています。また複数ノードを用いた設定はしていません。
gcc(OpenMP)の導入
OpenMPは、macの標準のCコンパイラ(clang)ではサポートされていないため、CコンパイラをOpenMPがサポートされているgccに切り替える必要があります。
※自分のアカウントが一般ユーザーの場合、スーパーユーザー(管理者権限を持つアカウント)または
sudo
コマンドを頭につけて行ってください。gccの有無確認
gcc -vバージョンが書いてあるところにHomebrewと書いてある場合、gccは入っているのでOpenMPも導入済です。
clangと書いてある場合、ややこしいですがgccは入っておらず、gcc
というコマンドでclangが代わりに起動するようになっているため、gccをインストールする必要があります。gccをインストール
brew install gccHomebrew経由でgcc, g++の最新版をインストール。
brew
コマンドがなければ入れておいてください。gccが入ってはいるが古い場合は、
brew upgrade gccでgcc, g++を最新版にしておくと良いですが不要かもしれません。
gccにシンボリックを貼る
ls /usr/local/bin | grep gcc ls /usr/local/bin | grep g++まずはインストールしたgcc, g++のバージョン確認。例えば
gcc-10
やg++-10
と返されれば、先程インストールしたgcc, g++はバージョン10です。ただこのままだと
gcc-10
と打たないとgccが起動しないので、gcc
と打てばgcc-10
が起動するようショートカット(シンボリック)を作成します。ln -s /usr/loca/bin/gcc-10 /usr/local/bin/gcc ln -s /usr/local/bin/g++-10 /usr/local/bin/g++gccの優先順位確認
which -a gccgccというコマンドで起動するコンパイラを全て表示します。
/usr/local/bin/gcc
と/usr/bin/gcc
の二つが返されると思いますが、前者はgcc, 後者はclangです。
gcc
とコマンドを打った際にどちらが起動するか確認します。which gcc
/usr/local/bin/gcc
と返されれば、gccが優先的に使用されるのでOpenMPの導入も完了です。OpenMPIの導入に移ってください。
/usr/bin/gcc
と返される場合、clangが優先的に使用されるのでgccを優先させる必要があります。gccへの切り替え(パスを通す)
※パスはユーザーごとに異なるため、一般ユーザーであればスーパーユーザーからアカウントを切り替えて行ってください
gccを優先させるために、
/usr/local/bin
にあるコマンドを優先させます(パスを通す)。
まずは自分が使用しているシェルを確認します。シェルによってパスの編集方法が若干変わってきます。echo $SHELL
/bin/zsh
のように返されれば使用シェルはzsh、/bin/bash
のように返されれば使用シェルはbashなので覚えておいてください(これら以外の可能性もあります)。次にホーム(
~
)に移動してファイル一覧を表示し、自分のPCにパスの編集用ファイルがあるか確認します。cd ~ ls -azshの場合は
ls -a
で表示されたファイルに.zshrcがあればそれが編集用ファイルです。bashの場合は.bash_profileや.bashrcが編集用ファイルです。編集用ファイルが無い場合は作成します(必ずホームで作成してください)。zshの方は、
touch .zshrcbashの方は、
touch .bash_profile .bashrc.bash_profileだけでも出来たりしますが今回は両方使用する設定を行います。
またbashの場合は事前準備として作成した.bash_profileに以下を書いてください。これが無いと.bashrcが自動で読み込まれません(zshの場合は自動で読み込まれるので以下の操作は必要ありません)。既にこの記述がある場合はそのままで大丈夫です。
.bash_profilesource ~/.bashrc
次にファイルにパスを通す記述をします。
.zshrcまたは.bashrcを開き、以下を書いてください。.zshrcまたは.bashrcexport PATH="/usr/local/bin:$PATH"編集が終わったら、設定を読み込むためターミナルを再起動してください。
再確認
which gcc
/usr/local/bin/gcc
と返ってくればgccが優先されています(gcc -v
でHomebrewと表示されるはずです)。OpenMPも同時に使用可能になっています。OpenMPIの導入
※またスーパーユーザーに戻るか必要に応じて
sudo
コマンドを用いて作業してくださいOpenMPIのインストール
http://www.open-mpi.org/software/ompi/
こちらから最新版のOpenMPIのバージョンを確認してください。今回は例としてバージョン4.0.5を使用します。ダウンロードしたい場所へ移動しダウンロードします(サイトから直接落としても可)。
cd ~/Desktop wget http://www.open-mpi.org/software/ompi/v4.0/downloads/openmpi-4.0.5.tar.gz
wget
コマンドが無い場合はbrew install wget
で入れておいてください。次に落としたものを解凍します。
tar xzvf openmpi-4.0.5.tar.gzこれでOpenMPIのフォルダが自動で生成されるので、フォルダに移動し作業を進めます。
cd openmpi-4.0.5
ls
コマンドでファイル一覧を見ればわかりますが、この時点ではMakefileがないので(Makefile.amなどは別物です)、作成する必要があります。./configure CC=gcc CXX=g++ F77=gfortran FC=gfortran --enable-mpi-thread-multiple --prefix=/usr/local/binここでCCはCのコンパイラ、CXXはC++のコンパイラ、F90, FCはfortranのコンパイラ、--prefixはインストール先のフォルダを指定します。
これを行うとMakefileなどが生成されます。
試していませんがfortranのコンパイラを入れておらず、fortranを使わないようであればF77, FCの指定はしなくて良いかもしれません。指定せずエラーが出た場合はfortranのコンパイラ(gfortran
など)も入れておいてください。コンパイルとインストール
Makefileが生成されている事を確認できたら、コンパイルを行い、それをインストールします。
make make installどちらもかなり時間がかかります。
権限が無い場合はsudo make
,sudo make install
。
またもしエラーなどが出てmake
をやり直す場合は、生成されたファイルを一度消した方が良いかもしれません(フォルダごと削除してダウンロードからやり直すと無難)。コマンドの確認
OpenMPIを使用する際のコマンドはcとc++でそれぞれ
mpicc
,mpic++
です。which mpicc which mpic++例えば
/usr/local/bin
と返されれば、そこにmpicc
,mpic++
コマンドがあります。
パスをいくつか設定する必要があるため、実際にインストールされたフォルダの場所を調べます。
上記のwhich
コマンドで返された場所へ移動し、OpenMPIの情報を見ますcd /usr/local/bin mpicc --version
Configured with:
の欄に、--prefix=インストールされたフォルダ
が書いてあるので、その場所(例えば/usr/local/Cellar/gcc/10.2.0
)をメモします。パスの編集
※gccの時と同様に、一般ユーザーであればアカウントを切り替えて行ってください
gccのパス設定と同様に、ホームに移動しパス編集用ファイルを開き以下を記述します。
.zshrcまたは.bashrc#openmpi export MANPATH=インストールしたフォルダ/share/man:$MANPATH export LD_LIBRARY_PATH=インストールしたフォルダ/lib:$LD_LIBRARY_PATH export PATH="インストールしたフォルダ/bin:$PATH"ここでのインストールしたフォルダは、先程
mpicc --version
で確認したフォルダです。編集が終わったら、設定を読み込むためターミナルを再起動してください。
確認
echo $PATH echo $MANPATH echo $LD_LIBRARY_PATH先程パス編集ファイルに記述した場所が含まれていればパスの設定は成功です。
mpicc
,mpic++
コマンドが無い場所へ移動し(cd ~
など)、mpicc --version mpic++ --versionこれで反応があればパスは通っています。OpenMPIが使用可能です。
サンプルプログラム
https://mpitutorial.com/tutorials/mpi-hello-world/ のMPIのサンプルプログラムに、OpenMPによる複数スレッドからの出力を追加しました。
touch sample.cppsample.cpp#include <stdio.h> #include <omp.h> #include <mpi.h> int main(){ //初期化 MPI_Init(NULL,NULL); //プロセス数(この計算全体で何コア使用しているか)の取得。実行時にコア数は指定できる。 int world_size; MPI_Comm_size(MPI_COMM_WORLD, &world_size); //ランク(現在何番目のコアで計算しているか)を取得 int world_rank; MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); //プロセッサー名を取得 char processor_name[MPI_MAX_PROCESSOR_NAME]; int name_len; MPI_Get_processor_name(processor_name, &name_len); //OpenMPによる並列化 #pragma omp parallel { //ランクが0でスレッドが0の時、プロセス数と1プロセスあたりのスレッド数を出力 if(world_rank==0 && omp_get_thread_num()==0){ printf("the number of processors : %d\n", world_size); printf("the number of threads per 1 process : %d\n", omp_get_num_threads()); } //出力している間他のスレッドはここで待機。不要かも。 #pragma omp barrier } //出力している間他のコアはここで待機。無くても良い。 MPI_Barrier(MPI_COMM_WORLD); //各プロセス、各スレッドから出力 #pragma omp parallel { printf("Hello world from processor %s, thread %d, rank %d\n", processor_name, omp_get_thread_num(), world_rank); } //終了処理 MPI_Finalize(); return 0; }MPIによるコア並列処理はプログラム実行時に指定しますが、OpenMPによるスレッド並列処理はプログラム内に逐一記述します。
OpenMPIのコンパイルはc,c++でそれぞれ
mpicc
,mpic++
で行います。またOpenMPを有効にするにはコンパイルオプションで指定する必要があります。オプションはコンパイラによって異なりますが、gccの場合は-fopenmp
です。mpic++ -fopenmp sample.cppまた使用するスレッド数(1プロセスあたり)はあらかじめ指定しておきます。指定する数字については下記の補足:コア数、スレッド数の上限を参照してください。
指定方法はbashやzshでは下記のようにexport OMP_NUM_THREADS=[スレッド数]
ですが、使用シェルによって変わります。また毎回同じ数を指定するのであれば、.bashrcや.zshrcに書いておくことでいちいち書かなくて良くなります。export OMP_NUM_THREADS=2今回は例として2個に指定しました。
実行は
mpirun
で行います(試していませんがmpiexec
でも出来るそうです)。mpirun -np 4 ./a.out
-np
または-n
でOpenMPIで使用するコア数(プロセス数)を指定します。例として4個としています。the number of processors : 4 the number of threads per 1 process : 2 Hello world from processor [プロセッサー名].local, thread 1, rank 0 Hello world from processor [プロセッサー名].local, thread 0, rank 0 Hello world from processor [プロセッサー名].local, thread 1, rank 1 Hello world from processor [プロセッサー名].local, thread 0, rank 1 Hello world from processor [プロセッサー名].local, thread 1, rank 2 Hello world from processor [プロセッサー名].local, thread 0, rank 2 Hello world from processor [プロセッサー名].local, thread 1, rank 3 Hello world from processor [プロセッサー名].local, thread 0, rank 3のように一度の実行でプロセス数×1プロセスあたりのスレッド数の数だけ
Hello world
が出力されていれば成功です。補足:コア数、スレッド数の上限
使用できるコア数はPCによって異なります。
PCの全コア数の確認は、system_profiler SPHardwareDataType
Total Number of Cores:
の値が使用できる最大のコア数です。またスレッド数はいくらでも増やせますが、全スレッド数(1プロセスあたりのスレッド数×プロセス数)がPCの論理コア数を越えると一度に処理が出来ないので計算が遅くなります。論理コア数の確認は、
sysctl -n hw.logicalcpu_maxまた論理コア数を上回っていなくても、コア数とスレッド数は大きくしすぎるとデータを各スレッド、各コアに分ける作業や各スレッド、各コアから集める作業で時間がかかる可能性があるので注意してください。
参考文献
- MacでMPIとopenmpをハイブリッドにつかえる環境を構築する
メインで参考にした記事です。大まかにはこちらの記事で十分です。- Open MPI
OpenMPIのダウンロードページです。- Open MPI Documentation
OpenMPIのバージョン毎の関数の説明があります。- MPI HELLO WORLD
サンプルプログラムを書く際に参考にしたページです。- OpenMPによるスレッド並列計算
OpenMPの概念と基本的な関数の説明です。- C言語によるOpenMP入門
コンパイラオプションや環境変数についても書いてあります。指示文の説明も参考にしました。
- 投稿日:2021-02-27T03:25:44+09:00
macOSでC, C++並列処理をするためのOpenMP, OpenMPI環境構築
2021/02/27投稿
はじめに
初投稿です。
自分がmacにOpenMPとOpenMPIを導入する際かなり混乱したため、自分のような初心者でもわかるように書きました。参考になれば幸いです。並列処理
プログラムは基本1つの実行に対して1つのコアかつ1つのスレッドしか使用しません。
そのためPC内の他のコアは常に暇しており、また計算以外の処理中などは使用しているコア自体も手持ち無沙汰になっています。
簡単なプログラムであれば問題ありませんが、プログラムによっては計算時間が非常にかかるため、暇している他のコアに仕事を振ったり、使用しているコアにもスレッドを分けて複数の仕事を与えたいところです。そこで並列処理を行います。プログラム内のデータを各スレッドや各コアに分散させ、計算が終わったところで各スレッドや各コアからデータを収集します。
今回導入するOpenMP、OpenMPIはそれぞれスレッド、コアを並列化することが出来ます。
OpenMPとOpenMPI
OpenMPはスレッド並列化を行うAPIです。1つのCPUが1つのコアしか持っていなくても、複数の処理を同時に行うことができます。
OpenMPIはMPI(Message Passing Interface)の一種で、プロセス自体を並列化するライブラリでありOpenMPとは全くの別物です。1つの命令を1つのコアではなく複数のコア(プロセス)を用いて処理します。これらを同時に使用することで、各コアがそれぞれ複数の処理を同時に行うことができるようになり、計算速度が上がります。
これらはfortran, C言語, C++で使用する事が出来ますが、今回はC言語, C++での設定を行います。またOpenMPIは複数ノードを用いた設定もありますが、今回はしていません。
環境
macOS Sierra 10.12.6
macOS Mojave 10.14.6
macOS Catalina 10.15.7gcc(OpenMP)の導入
OpenMPはmacの標準のCコンパイラ(clang)ではサポートされていないため、CコンパイラをOpenMPがサポートされているgccに切り替える必要があります。
※自分のアカウントが一般ユーザーの場合、スーパーユーザー(管理者権限を持つアカウント)または
sudo
コマンドを頭につけて行ってください。gccの有無確認
gcc -vバージョンが書いてあるところにHomebrewと書いてある場合、gccは入っているのでOpenMPも導入済です。
clangと書いてある場合、ややこしいですがgccは入っておらず、gcc
というコマンドでclangが代わりに起動するようになっているため、gccをインストールする必要があります。gccをインストール
brew install gccHomebrew経由でgcc, g++の最新版をインストール。
brew
コマンドがなければ入れておいてください。gccが入ってはいるが古い場合は、
brew upgrade gccでgcc, g++を最新版にしておくと良いですが不要かもしれません。
gccにシンボリックを貼る
ls /usr/local/bin | grep gcc ls /usr/local/bin | grep g++まずはインストールしたgcc, g++のバージョン確認。例えば
gcc-10
やg++-10
と返されれば、先程インストールしたgcc, g++はバージョン10です。ただこのままだと
gcc-10
と打たないとgccが起動しないので、gcc
と打てばgcc-10
が起動するようショートカット(シンボリック)を作成します。ln -s /usr/loca/bin/gcc-10 /usr/local/bin/gcc ln -s /usr/local/bin/g++-10 /usr/local/bin/g++gccの優先順位確認
which -a gccgccというコマンドで起動するコンパイラを全て表示します。
/usr/local/bin/gcc
と/usr/bin/gcc
の二つが返されると思いますが、前者はgcc, 後者はclangです。
gcc
とコマンドを打った際にどちらが起動するか確認します。which gcc
/usr/local/bin/gcc
と返されれば、gccが優先的に使用されるのでOpenMPの導入も完了です。OpenMPIの導入に移ってください。
/usr/bin/gcc
と返される場合、clangが優先的に使用されるのでgccを優先させる必要があります。gccへの切り替え(パスを通す)
※パスはユーザーごとに異なるため、一般ユーザーであればスーパーユーザーからアカウントを切り替えて行ってください
gccを優先させるために、
/usr/local/bin
にあるコマンドを優先させます(パスを通す)。
まずは自分が使用しているシェルを確認します。シェルによってパスの編集方法が若干変わってきます。echo $SHELL
/bin/zsh
のように返されれば使用シェルはzsh、/bin/bash
のように返されれば使用シェルはbashなので覚えておいてください(これら以外の可能性もあります)。次にホーム(
~
)に移動してファイル一覧を表示し、自分のPCにパスの編集用ファイルがあるか確認します。cd ~ ls -azshの場合は
ls -a
で表示されたファイルに.zshrcがあればそれが編集用ファイルです。bashの場合は.bash_profileや.bashrcが編集用ファイルです。編集用ファイルが無い場合は作成します(必ずホームで作成してください)。zshの方は、
touch .zshrcbashの方は、
touch .bash_profile .bashrc.bash_profileだけでも出来たりしますが今回は両方使用する設定を行います。
またbashの場合は事前準備として作成した.bash_profileに、以下を書いてください。これが無いと.bashrcが自動で読み込まれません(zshの場合は自動で読み込まれるので以下の操作は必要ありません)。既にこの記述がある場合はそのままで大丈夫です。
.bash_profilesource ~/.bashrc
次にファイルにパスを通す記述をします。
.zshrcまたは.bashrcを開き、以下を書いてください。.zshrcまたは.bashrcexport PATH="/usr/local/bin:$PATH"編集が終わったら、設定を読み込むためターミナルを再起動してください。
再確認
which gcc
/usr/local/bin/gcc
と返ってくればgccが優先されています(gcc -v
でHomebrewと表示されるはずです)。OpenMPも同時に使用可能になっています。OpenMPIの導入
※またスーパーユーザーに戻るか必要に応じて
sudo
コマンドを用いて作業してくださいOpenMPIのインストール
http://www.open-mpi.org/software/ompi/
こちらから最新版のOpenMPIのバージョンを確認してください。今回は例としてバージョン4.0.5を使用します。ダウンロードしたい場所へ移動しダウンロードします(サイトから直接落としても可)。
cd ~/Desktop wget http://www.open-mpi.org/software/ompi/v4.0/downloads/openmpi-4.0.5.tar.gz
wget
コマンドが無い場合はbrew install wget
で入れておいてください。次に落としたものを解凍します。
tar xzvf openmpi-4.0.5.tar.gzこれでOpenMPIのフォルダが自動で生成されるので、フォルダに移動し作業を進めます。
cd openmpi-4.0.5
ls
コマンドでファイル一覧を見ればわかりますが、この時点ではMakefileがないので(Makefile.amなどは別物です)、作成する必要があります。./configure CC=gcc CXX=g++ F77=gfortran FC=gfortran --enable-mpi-thread-multiple --prefix=/usr/local/binここでCCはCのコンパイラ、CXXはC++のコンパイラ、F90, FCはfortranのコンパイラ、--prefixはインストール先のフォルダを指定します。
これを行うとMakefileなどが生成されます。
試していませんがfortranのコンパイラを入れておらず、fortranを使わないようであればF77, FCの指定はしなくて良いかもしれません。指定せずエラーが出た場合はfortranのコンパイラ(gfortran
など)も入れておいてください。コンパイルとインストール
Makefileが生成されている事を確認できたら、コンパイルを行い、それをインストールします。
make make installどちらもかなり時間がかかります。
権限が無い場合はsudo make
,sudo make install
。
またもしエラーなどが出てmake
をやり直す場合は、生成されたファイルを一度消した方が良いかもしれません(フォルダごと削除してダウンロードからやり直すと無難)。コマンドの確認
OpenMPIを使用する際のコマンドはcとc++でそれぞれ
mpicc
,mpic++
です。which mpicc which mpic++例えば
/usr/local/bin
と返されれば、そこにmpicc
,mpic++
コマンドがあります。
パスをいくつか設定する必要があるため、実際にインストールされたフォルダの場所を調べます。
上記のwhich
コマンドで返された場所へ移動し、OpenMPIの情報を見ますcd /usr/local/bin mpicc --version
Configured with:
の欄に、--prefix=インストールされたフォルダ
が書いてあるので、その場所(例えば/usr/local/Cellar/gcc/10.2.0
)をメモします。パスの編集
※gccの時と同様に、一般ユーザーであればアカウントを切り替えて行ってください
gccのパス設定と同様に、ホームに移動しパス編集用ファイルを開き以下を記述します。
.zshrcまたは.bashrc#openmpi export MANPATH=インストールしたフォルダ/share/man:$MANPATH export LD_LIBRARY_PATH=インストールしたフォルダ/lib:$LD_LIBRARY_PATH export PATH="インストールしたフォルダ/bin:$PATH"ここでのインストールしたフォルダは、先程
mpicc --version
で確認したフォルダです。編集が終わったら、設定を読み込むためターミナルを再起動してください。
確認
echo $PATH echo $MANPATH echo $LD_LIBRARY_PATH先程パス編集ファイルに記述した場所が含まれていればパスの設定は成功です。
mpicc
,mpic++
コマンドが無い場所へ移動し(cd ~
など)、mpicc --version mpic++ --versionこれで反応があればパスは通っています。OpenMPIが使用可能です。
サンプルプログラム
https://mpitutorial.com/tutorials/mpi-hello-world/
こちらのMPIのサンプルプログラムに、OpenMPによる複数スレッドからの出力を追加しました。touch sample.cppsample.cpp#include <stdio.h> #include <omp.h> #include <mpi.h> int main(){ //初期化 MPI_Init(NULL,NULL); //プロセス数(この計算全体で何コア使用しているか)の取得。実行時にコア数は指定できる。 int world_size; MPI_Comm_size(MPI_COMM_WORLD, &world_size); //ランク(現在何番目のコアで計算しているか)を取得 int world_rank; MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); //プロセッサー名を取得 char processor_name[MPI_MAX_PROCESSOR_NAME]; int name_len; MPI_Get_processor_name(processor_name, &name_len); //OpenMPによる並列化 #pragma omp parallel { //ランクが0でスレッドが0の時、プロセス数と1プロセスあたりのスレッド数を出力 if(world_rank==0 && omp_get_thread_num()==0){ printf("the number of processors : %d\n", world_size); printf("the number of threads per 1 process : %d\n", omp_get_num_threads()); } //出力している間他のスレッドはここで待機。不要かも。 #pragma omp barrier } //出力している間他のコアはここで待機。無くても良い。 MPI_Barrier(MPI_COMM_WORLD); //各プロセス、各スレッドから出力 #pragma omp parallel { printf("Hello world from processor %s, thread %d, rank %d\n", processor_name, omp_get_thread_num(), world_rank); } //終了処理 MPI_Finalize(); return 0; }MPIによるコア並列処理はプログラム実行時に指定しますが、OpenMPによるスレッド並列処理はプログラム内に逐一記述します。
OpenMPIのコンパイルはc,c++でそれぞれ
mpicc
,mpic++
で行います。またOpenMPを有効にするにはコンパイルオプションで指定する必要があります。オプションはコンパイラによって異なりますが、gccの場合は-fopenmp
です。mpic++ -fopenmp sample.cppまた使用するスレッド数(1プロセスあたり)はあらかじめ指定しておきます。指定する数字については下記の補足:コア数、スレッド数の上限を参照してください。
指定方法はbashやzshでは下記のようにexport OMP_NUM_THREADS=[スレッド数]
ですが、使用シェルによって変わります。また毎回同じ数を指定するのであれば、.bashrcや.zshrcに書いておくことでいちいち書かなくて良くなります。export OMP_NUM_THREADS=2今回は例として2個に指定しました。
実行は
mpirun
で行います(試していませんがmpiexec
でも出来るそうです)。mpirun -np 4 ./a.out
-np
または-n
でOpenMPIで使用するコア数(プロセス数)を指定します。例として4個としています。the number of processors : 4 the number of threads per 1 process : 2 Hello world from processor [プロセッサー名].local, thread 1, rank 0 Hello world from processor [プロセッサー名].local, thread 0, rank 0 Hello world from processor [プロセッサー名].local, thread 1, rank 1 Hello world from processor [プロセッサー名].local, thread 0, rank 1 Hello world from processor [プロセッサー名].local, thread 1, rank 2 Hello world from processor [プロセッサー名].local, thread 0, rank 2 Hello world from processor [プロセッサー名].local, thread 1, rank 3 Hello world from processor [プロセッサー名].local, thread 0, rank 3のように一度の実行でプロセス数×1プロセスあたりのスレッド数の数だけ
Hello world
が出力されていれば成功です。補足:コア数、スレッド数の上限
使用できるコア数はPCによって異なります。
PCの全コア数の確認は、system_profiler SPHardwareDataType
Total Number of Cores:
の値が使用できる最大のコア数です。単一ノードの場合これ以上の数字は指定出来ません。またスレッド数はいくらでも増やせますが、全スレッド数(1プロセスあたりのスレッド数×プロセス数)がPCの論理コア数を越えると一度に処理が出来ないので計算が遅くなります。論理コア数の確認は、
sysctl -n hw.logicalcpu_maxまた論理コア数を上回っていなくても、コア数とスレッド数は大きくしすぎるとデータを各スレッド、各コアに分ける作業や各スレッド、各コアから集める作業で時間がかかる可能性があるので注意してください。
参考文献
- MacでMPIとopenmpをハイブリッドにつかえる環境を構築する - Qiita
メインで参考にした記事です。大まかにはこちらの記事で十分です。- Open MPI
OpenMPIのダウンロードページです。- Open MPI Documentation
OpenMPIのバージョン毎の関数の説明があります。- MPI HELLO WORLD - MPI Tutorial
サンプルプログラムを書く際に参考にしたページです。- OpenMPによるスレッド並列計算
OpenMPの概念と基本的な関数の説明を参考にしました。- C言語によるOpenMP入門
コンパイラオプションや環境変数についても書いてあります。指示文の説明も参考にしました。
- 投稿日:2021-02-27T03:25:44+09:00
macOSでのOpenMP, OpenMPIの環境構築
2021/02/27更新
はじめに
初投稿です。
自分がmacにOpenMPとOpenMPIを導入する際かなり混乱したため、自分のような初心者でもわかるように書きました。参考になれば幸いです。基本的にはfortranではなくC,C++を想定しています。また複数ノードを用いた設定はしていません。
環境
macOS Sierra 10.12.6
macOS Mojave 10.14.6
macOS Catalina 10.15.7OpenMPとOpenMPI
OpenMPはスレッド並列化を行うAPIです。1つのCPUが1つのコアしか持っていなくても、複数の処理を同時に行うことができます。
OpenMPIはMPI(Message Passing Interface)の一種で、プロセス自体を並列化するライブラリでありOpenMPとは全くの別物です。1つの命令を1つのコアではなく複数のコア(プロセス)を用いて処理します。これらを同時に使用することで、各コアがそれぞれ複数の処理を同時に行うことができるようになり、計算速度が上がります。
gcc(OpenMP)の導入
OpenMPは、macの標準のCコンパイラ(clang)ではサポートされていないため、CコンパイラをOpenMPがサポートされているgccに切り替える必要があります。
※自分のアカウントが一般ユーザーの場合、スーパーユーザー(管理者権限を持つアカウント)または
sudo
コマンドを頭につけて行ってください。gccの有無確認
gcc -vバージョンが書いてあるところにHomebrewと書いてある場合、gccは入っているのでOpenMPも導入済です。
clangと書いてある場合、ややこしいですがgccは入っておらず、gcc
というコマンドでclangが代わりに起動するようになっているため、gccをインストールする必要があります。gccをインストール
brew install gccHomebrew経由でgcc, g++の最新版をインストール。
brew
コマンドがなければ入れておいてください。gccが入ってはいるが古い場合は、
brew upgrade gccでgcc, g++を最新版にしておくと良いですが不要かもしれません。
gccにシンボリックを貼る
ls /usr/local/bin | grep gcc ls /usr/local/bin | grep g++まずはインストールしたgcc, g++のバージョン確認。例えば
gcc-10
やg++-10
と返されれば、先程インストールしたgcc, g++はバージョン10です。ただこのままだと
gcc-10
と打たないとgccが起動しないので、gcc
と打てばgcc-10
が起動するようショートカット(シンボリック)を作成します。ln -s /usr/loca/bin/gcc-10 /usr/local/bin/gcc ln -s /usr/local/bin/g++-10 /usr/local/bin/g++gccの優先順位確認
which -a gccgccというコマンドで起動するコンパイラを全て表示します。
/usr/local/bin/gcc
と/usr/bin/gcc
の二つが返されると思いますが、前者はgcc, 後者はclangです。
gcc
とコマンドを打った際にどちらが起動するか確認します。which gcc
/usr/local/bin/gcc
と返されれば、gccが優先的に使用されるのでOpenMPの導入も完了です。OpenMPIの導入に移ってください。
/usr/bin/gcc
と返される場合、clangが優先的に使用されるのでgccを優先させる必要があります。gccへの切り替え(パスを通す)
※パスはユーザーごとに異なるため、一般ユーザーであればスーパーユーザーからアカウントを切り替えて行ってください
gccを優先させるために、
/usr/local/bin
にあるコマンドを優先させます(パスを通す)。
まずは自分が使用しているシェルを確認します。シェルによってパスの編集方法が若干変わってきます。echo $SHELL
/bin/zsh
のように返されれば使用シェルはzsh、/bin/bash
のように返されれば使用シェルはbashなので覚えておいてください(これら以外の可能性もあります)。次にホーム(
~
)に移動してファイル一覧を表示し、自分のPCにパスの編集用ファイルがあるか確認します。cd ~ ls -azshの場合は
ls -a
で表示されたファイルに.zshrcがあればそれが編集用ファイルです。bashの場合は.bash_profileや.bashrcが編集用ファイルです。編集用ファイルが無い場合は作成します(必ずホームで作成してください)。zshの方は、
touch .zshrcbashの方は、
touch .bash_profile .bashrc.bash_profileだけでも出来たりしますが今回は両方使用する設定を行います。
またbashの場合は事前準備として作成した.bash_profileに以下を書いてください。これが無いと.bashrcが自動で読み込まれません(zshの場合は自動で読み込まれるので以下の操作は必要ありません)。既にこの記述がある場合はそのままで大丈夫です。
.bash_profilesource ~/.bashrc
次にファイルにパスを通す記述をします。
.zshrcまたは.bashrcを開き、以下を書いてください。.zshrcまたは.bashrcexport PATH="/usr/local/bin:$PATH"編集が終わったら、設定を読み込むためターミナルを再起動してください。
再確認
which gcc
/usr/local/bin/gcc
と返ってくればgccが優先されています(gcc -v
でHomebrewと表示されるはずです)。OpenMPも同時に使用可能になっています。OpenMPIの導入
※またスーパーユーザーに戻るか必要に応じて
sudo
コマンドを用いて作業してくださいOpenMPIのインストール
http://www.open-mpi.org/software/ompi/
こちらから最新版のOpenMPIのバージョンを確認してください。今回は例としてバージョン4.0.5を使用します。ダウンロードしたい場所へ移動しダウンロードします(サイトから直接落としても可)。
cd ~/Desktop wget http://www.open-mpi.org/software/ompi/v4.0/downloads/openmpi-4.0.5.tar.gz
wget
コマンドが無い場合はbrew install wget
で入れておいてください。次に落としたものを解凍します。
tar xzvf openmpi-4.0.5.tar.gzこれでOpenMPIのフォルダが自動で生成されるので、フォルダに移動し作業を進めます。
cd openmpi-4.0.5
ls
コマンドでファイル一覧を見ればわかりますが、この時点ではMakefileがないので(Makefile.amなどは別物です)、作成する必要があります。./configure CC=gcc CXX=g++ F77=gfortran FC=gfortran --enable-mpi-thread-multiple --prefix=/usr/local/binここでCCはCのコンパイラ、CXXはC++のコンパイラ、F90, FCはfortranのコンパイラ、--prefixはインストール先のフォルダを指定します。
これを行うとMakefileなどが生成されます。
試していませんがfortranのコンパイラを入れておらず、fortranを使わないようであればF77, FCの指定はしなくて良いかもしれません。指定せずエラーが出た場合はfortranのコンパイラ(gfortran
など)も入れておいてください。コンパイルとインストール
Makefileが生成されている事を確認できたら、コンパイルを行い、それをインストールします。
make make installどちらもかなり時間がかかります。
権限が無い場合はsudo make
,sudo make install
。
またもしエラーなどが出てmake
をやり直す場合は、生成されたファイルを一度消した方が良いかもしれません(フォルダごと削除してダウンロードからやり直すと無難)。コマンドの確認
OpenMPIを使用する際のコマンドはcとc++でそれぞれ
mpicc
,mpic++
です。which mpicc which mpic++例えば
/usr/local/bin
と返されれば、そこにmpicc
,mpic++
コマンドがあります。
パスをいくつか設定する必要があるため、実際にインストールされたフォルダの場所を調べます。
上記のwhich
コマンドで返された場所へ移動し、OpenMPIの情報を見ますcd /usr/local/bin mpicc --version
Configured with:
の欄に、--prefix=インストールされたフォルダ
が書いてあるので、その場所(例えば/usr/local/Cellar/gcc/10.2.0
)をメモします。パスの編集
※gccの時と同様に、一般ユーザーであればアカウントを切り替えて行ってください
gccのパス設定と同様に、ホームに移動しパス編集用ファイルを開き以下を記述します。
.zshrcまたは.bashrc#openmpi export MANPATH=インストールしたフォルダ/share/man:$MANPATH export LD_LIBRARY_PATH=インストールしたフォルダ/lib:$LD_LIBRARY_PATH export PATH="インストールしたフォルダ/bin:$PATH"ここでのインストールしたフォルダは、先程
mpicc --version
で確認したフォルダです。編集が終わったら、設定を読み込むためターミナルを再起動してください。
確認
echo $PATH echo $MANPATH echo $LD_LIBRARY_PATH先程パス編集ファイルに記述した場所が含まれていればパスの設定は成功です。
mpicc
,mpic++
コマンドが無い場所へ移動し(cd ~
など)、mpicc --version mpic++ --versionこれで反応があればパスは通っています。OpenMPIが使用可能です。
サンプルプログラム
https://mpitutorial.com/tutorials/mpi-hello-world/ のMPIのサンプルプログラムに、OpenMPによる複数スレッドからの出力を追加しました。
touch sample.cppsample.cpp#include <stdio.h> #include <omp.h> #include <mpi.h> int main(){ //初期化 MPI_Init(NULL,NULL); //プロセス数(この計算全体で何コア使用しているか)の取得。実行時にコア数は指定できる。 int world_size; MPI_Comm_size(MPI_COMM_WORLD, &world_size); //ランク(現在何番目のコアで計算しているか)を取得 int world_rank; MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); //プロセッサー名を取得 char processor_name[MPI_MAX_PROCESSOR_NAME]; int name_len; MPI_Get_processor_name(processor_name, &name_len); //OpenMPによる並列化 #pragma omp parallel { //ランクが0でスレッドが0の時、プロセス数と1プロセスあたりのスレッド数を出力 if(world_rank==0 && omp_get_thread_num()==0){ printf("the number of processors : %d\n", world_size); printf("the number of threads per 1 process : %d\n", omp_get_num_threads()); } //出力している間他のスレッドはここで待機。不要かも。 #pragma omp barrier } //出力している間他のコアはここで待機。無くても良い。 MPI_Barrier(MPI_COMM_WORLD); //各プロセス、各スレッドから出力 #pragma omp parallel { printf("Hello world from processor %s, thread %d, rank %d\n", processor_name, omp_get_thread_num(), world_rank); } //終了処理 MPI_Finalize(); return 0; }MPIによるコア並列処理はプログラム実行時に指定しますが、OpenMPによるスレッド並列処理はプログラム内に逐一記述します。
OpenMPIのコンパイルはc,c++でそれぞれ
mpicc
,mpic++
で行います。またOpenMPを有効にするにはコンパイルオプションで指定する必要があります。オプションはコンパイラによって異なりますが、gccの場合は-fopenmp
です。mpic++ -fopenmp sample.cppまた使用するスレッド数(1プロセスあたり)はあらかじめ指定しておきます。指定する数字については下記の補足:コア数、スレッド数の上限を参照してください。
指定方法はbashやzshでは下記のようにexport OMP_NUM_THREADS=[スレッド数]
ですが、使用シェルによって変わります。また毎回同じ数を指定するのであれば、.bashrcや.zshrcに書いておくことでいちいち書かなくて良くなります。export OMP_NUM_THREADS=2今回は例として2個に指定しました。
実行は
mpirun
で行います(試していませんがmpiexec
でも出来るそうです)。mpirun -np 4 ./a.out
-np
または-n
でOpenMPIで使用するコア数(プロセス数)を指定します。例として4個としています。the number of processors : 4 the number of threads per 1 process : 2 Hello world from processor [プロセッサー名].local, thread 1, rank 0 Hello world from processor [プロセッサー名].local, thread 0, rank 0 Hello world from processor [プロセッサー名].local, thread 1, rank 1 Hello world from processor [プロセッサー名].local, thread 0, rank 1 Hello world from processor [プロセッサー名].local, thread 1, rank 2 Hello world from processor [プロセッサー名].local, thread 0, rank 2 Hello world from processor [プロセッサー名].local, thread 1, rank 3 Hello world from processor [プロセッサー名].local, thread 0, rank 3のように一度の実行でプロセス数×1プロセスあたりのスレッド数の数だけ
Hello world
が出力されていれば成功です。補足:コア数、スレッド数の上限
使用できるコア数はPCによって異なります。
PCの全コア数の確認は、system_profiler SPHardwareDataType
Total Number of Cores:
の値が使用できる最大のコア数です。またスレッド数はいくらでも増やせますが、全スレッド数(1プロセスあたりのスレッド数×プロセス数)がPCの論理コア数を越えると一度に処理が出来ないので計算が遅くなります。論理コア数の確認は、
sysctl -n hw.logicalcpu_maxまた論理コア数を上回っていなくても、コア数とスレッド数は大きくしすぎるとデータを各スレッド、各コアに分ける作業や各スレッド、各コアから集める作業で時間がかかる可能性があるので注意してください。
参考文献
- MacでMPIとopenmpをハイブリッドにつかえる環境を構築する
メインで参考にした記事です。大まかにはこちらの記事で十分です。- Open MPI
OpenMPIのダウンロードページです。- Open MPI Documentation
OpenMPIのバージョン毎の関数の説明があります。- MPI HELLO WORLD
サンプルプログラムを書く際に参考にしたページです。- OpenMPによるスレッド並列計算
OpenMPの概念と基本的な関数の説明です。- C言語によるOpenMP入門
コンパイラオプションや環境変数についても書いてあります。指示文の説明も参考にしました。