mcpField
M
mpi

mpi

github.com/mohitmishra786開発269286 回インストール18 週間前に更新
リポジトリ

mpi について

mpiは、MPIプログラミングを扱うエージェント向けスキルです。通信パターン、ハイブリッド並列、ジョブ起動、デバッグを解説し、ノードやソケットをまたぐHPCアプリの開発・実行を支援します。

主な機能

  1. 01ポイントツーポイント通信と集合通信
  2. 02ノンブロッキング通信と処理の重畳
  3. 03サブコミュニケーターとMPI+OpenMP
  4. 04mpirunやスケジューラーによる起動
  5. 05MPI-IOと性能問題の調査

活用シーン

  1. 01ノード間の計算並列化
  2. 02行列分解やFFTの実装
  3. 03MPIプロセスとOpenMPスレッドの併用
  4. 04デッドロックの調査と並列ファイルI/O

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mohitmishra786/low-level-dev-skills --skill mpi

インストール後、Claude Code で/mpiを入力して読み込まれたか確認します。

詳細

MPI

目的

エージェントがMPI(メッセージパッシングインターフェース)プログラミングに取り組めるよう、ポイントツーポイント通信と集合通信、ノンブロッキング操作、サブコミュニケーター、MPI+OpenMPのハイブリッドパターン、mpirunによるプロセスの起動、デバッグ手法、MPI-IO、よくあるパフォーマンスの問題を説明します。

使用する場面

  • 複数のノードまたはソケットに処理を並列化する場合
  • 分散アルゴリズム(行列分解、FFT)を実装する場合
  • MPIのプロセス並列化とOpenMPのスレッド並列化を組み合わせる場合
  • Slurm/PBSとmpirunを使ってHPCジョブを実行する場合
  • デッドロックやメッセージの不一致をデバッグする場合
  • MPI-IOで並列ファイルI/Oを行う場合

ワークフロー

1. 最小限のMPIプログラム
#include <mpi.h>
#include <stdio.h>

int main(int argc, char **argv) {
    MPI_Init(&argc, &argv);

    int rank, size;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    printf("Hello from rank %d of %d\n", rank, size);

    MPI_Finalize();
    return 0;
}
mpicc -o hello hello.c
mpirun -np 4 ./hello
# or
mpiexec -n 4 ./hello
2. ポイントツーポイント通信
if (rank == 0) {
    int data = 42;
    MPI_Send(&data, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
} else if (rank == 1) {
    int recv;
    MPI_Recv(&recv, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    printf("rank 1 got %d\n", recv);
}

タグ付きメッセージでは、MPI_Recvのタグと送信元を一致させます。

3. 集合通信
int local = rank + 1;
int global_sum;

MPI_Allreduce(&local, &global_sum, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);

// Broadcast
if (rank == 0) data = 100;
MPI_Bcast(&data, 1, MPI_INT, 0, MPI_COMM_WORLD);

// Scatter/Gather
MPI_Scatter(sendbuf, sendcount, MPI_INT, recvbuf, recvcount, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Gather(sendbuf, sendcount, MPI_INT, recvbuf, recvcount, MPI_INT, 0, MPI_COMM_WORLD);
集合通信目的
MPI_Bcast1対全
MPI_Scatterチャンクを分配する
MPI_Gatherチャンクを集約する
MPI_Allreduceリデュースして結果をブロードキャストする
MPI_Barrier同期
MPI_Alltoall全対全交換
4. ノンブロッキング通信
MPI_Request req;
MPI_Isend(buf, count, MPI_INT, dest, tag, MPI_COMM_WORLD, &req);
// overlap computation here
do_local_work();
MPI_Wait(&req, MPI_STATUS_IGNORE);

// Multiple requests
MPI_Request reqs[2];
MPI_Irecv(buf0, n, MPI_INT, 0, 0, comm, &reqs[0]);
MPI_Irecv(buf1, n, MPI_INT, 1, 0, comm, &reqs[1]);
MPI_Waitall(2, reqs, MPI_STATUSES_IGNORE);

通信と計算を重ねて、レイテンシーを隠します。

5. サブコミュニケーター
int color = rank / 4;  // groups of 4
MPI_Comm subcomm;
MPI_Comm_split(MPI_COMM_WORLD, color, rank, &subcomm);

int subrank, subsize;
MPI_Comm_rank(subcomm, &subrank);
MPI_Comm_size(subcomm, &subsize);

MPI_Comm_free(&subcomm);
6. MPI + OpenMPのハイブリッド
#pragma omp parallel
{
    int tid = omp_get_thread_num();
    // thread-local work on rank's data partition
}
MPI_Barrier(MPI_COMM_WORLD);
MPI_Allreduce(...);
export OMP_NUM_THREADS=4
mpirun -np 8 --bind-to core ./hybrid_app
# 8 ranks × 4 threads = 32 cores

--map-by ppr:2:socketを使ってランクをソケットにバインドします。

7. ホストファイルを使った起動
# hostfile:
# node0 slots=4
# node1 slots=4

mpirun -np 8 --hostfile hosts.txt ./app

# Slurm integration
srun -n 64 ./app
# or
mpirun -np $SLURM_NTASKS ./app
# Debug: tag output by rank
mpirun -np 4 --tag-output ./app

# Sequential debug (one rank at a time)
mpirun -np 4 -gdb ./app
8. MPI-IO
#include <mpi.h>

MPI_File fh;
MPI_File_open(MPI_COMM_WORLD, "output.dat",
    MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);

MPI_Offset offset = rank * chunk_size;
MPI_File_write_at(fh, offset, buf, count, MPI_DOUBLE, MPI_STATUS_IGNORE);

MPI_File_close(&fh);

パフォーマンスを向上させる集合I/O:

MPI_File_write_at_all(fh, offset, buf, count, MPI_DOUBLE, MPI_STATUS_IGNORE);
9. パフォーマンスの問題
Common bottlenecks
├── Load imbalance → dynamic scheduling (OpenMP) or redistribute MPI chunks
├── Serialization at rank 0 → tree-based reduce, parallel I/O
├── Excessive sync → replace Barrier with point-to-point where possible
├── Small messages → aggregate; use MPI_Pack or larger blocks
└── Alltoall on large process counts → consider MPI neighborhood collectives
# MPI profiling
mpiP  # lightweight profiler
# or IPM, TAU MPI wrappers

よくある問題

症状原因修正方法
MPI_Recvで停止するタグまたは送信元の不一致Send/Recvの組み合わせを確認し、デバッグ時はMPI_ANY_TAGを使う
デッドロック循環待ち通信パターンの順序を変更するか、ノンブロッキング通信を使う
Allreduceの結果が正しくないデータ型またはカウントが誤っているMPI_INTとMPI_DOUBLEのどちらを使うか確認する
スケーリングが悪いRank 0がボトルネックになっているI/Oと集約を分散する
MPI_ERR_TRUNCATE受信バッファーが小さすぎる送信数と受信数を一致させる
ハイブリッド実行時の過剰割り当てスレッド数×ランク数が多すぎるOMP_NUM_THREADS = cores/ranks

関連スキル

  • skills/hpc/openmp — MPIランク内のスレッドレベルの並列化
  • skills/hpc/rdma-verbs — MPIでの低レイテンシー相互接続
  • skills/allocators/numa-programming — ランクをNUMAノードにバインドする
  • skills/profilers/linux-perf — MPIランクのホットスポットをプロファイリングする
  • skills/debuggers/gdb — 個々のMPIプロセスをデバッグする
  • skills/compilers/gcc — MPIコンパイラーラッパーのフラグ

コメント