LoginSignup
6
2

More than 5 years have passed since last update.

MPIプログラムからMPIプログラムをstd::systemで呼び出すと問題を起こす

Posted at

はじめに

これはMPI Advent Calendar 2017の7日目の記事です。「この辺でもう遠慮しようと思います」とか書いた気がしますがあれは嘘です。

並列コードを書くまでもない自明並列、いわゆる「バカパラ」をしたいときが結構あります。例えば大量のデータを処理したい、多数のフレームのレンダリングをしたい、などです。こんな要望に例えば「バルクジョブ」という形でシステム側で対応してくれているサイトもありますが、単純並列の場合は、MPIのラッパーを書いて、実行したいプログラムをstd::systemで呼び出す、ということをよくやります。

しかし、この子プロセスとして呼び出されるコードが、普通のシリアルプログラムではなく、MPIがリンクされた並列コードだと問題を起こすため、それについて紹介します。サンプルコードは

に置いておきます。

サンプルコード

まず、親プロセス側(呼び出し側)としてこんなコードを書きます。

a.cpp
#include <cstdio>
#include <cstdlib>
#include <mpi.h>

int main(int argc, char **argv) {
  MPI_Init(&argc, &argv);
  std::system("./b.out");
  MPI_Finalize();
}

単にstd::systemb.outを実行するだけのコードです。

子プロセス側(呼び出され側)としてこんなコードを書いてみます。

b.cpp
#include <cstdio>
#include <mpi.h>

int main(int argc, char **argv) {
  MPI_Init(&argc, &argv);
  printf("Hello World\n");
  MPI_Finalize();
}

何もせず、"Hello World"と表示するだけのコードです。ただしMPI_InitMPI_Finalizeは呼び出します。

さて、これをコンパイル、実行します。以下はMac上のOpen MPIの場合です。

$ mpicxx a.cpp -o a.out 
$ mpicxx b.cpp -o b.out
$ mpiexec -np 2 ./a.out
Hello World
Hello World # ← ここでプログラム実行が止まり、正常終了しない

一応コードは実行できますが、最後で止まってしまいます。ここでCtrl+Cを押すとSIGSEGVを吐いて異常終了します。

別サイトでIntel MPIで実行してみると、やはり実行はできますが最後に

===================================================================================
=   BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
=   PID XXXX RUNNING AT hostname
=   EXIT CODE: 13
=   CLEANING UP REMAINING PROCESSES
=   YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================

みたいなエラーを吐いて死にます。

まとめ

MPIプログラムからstd::systemを使って子プロセスを大量に実行する、というのはよくやっていたのですが、子プロセスとしてMPIプログラムを実行すると異常終了する、というのは知らなかったのでシェアしてみました。よく考えると、MPIを多段実行していることになり、MPI_Finalizeがおかしくなるのはわかる気がしますが、実際そう言われるまでは気が付きませんでした。

6
2
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
6
2