mcpField
M
mpi

mpi

github.com/mohitmishra786Development269286 installsUpdated 18w ago
Repository

About mpi

mpi is an agent skill for MPI programming, covering communication patterns, hybrid parallelism, job launching, and debugging. It is intended for developers building and running HPC applications across nodes or sockets.

Key features

  1. 01Point-to-point and collective communication
  2. 02Non-blocking communication and overlap
  3. 03Subcommunicators and MPI+OpenMP
  4. 04Launch with mpirun and schedulers
  5. 05MPI-IO and performance troubleshooting

Use cases

  1. 01Parallelize computation across nodes
  2. 02Implement matrix decomposition or FFT
  3. 03Combine MPI processes with OpenMP threads
  4. 04Debug deadlocks and use parallel file I/O

Install

Copy the command and run it in a terminal.

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

After installing, type/mpiin Claude Code to confirm it loaded.

Details

From the project README

MPI

Purpose

Guide agents through MPI (Message Passing Interface) programming: point-to-point and collective communication, non-blocking operations, subcommunicators, MPI+OpenMP hybrid patterns, process launching with mpirun, debugging techniques, MPI-IO, and common performance issues.

When to Use

  • Parallelizing across multiple nodes or sockets
  • Implementing distributed algorithms (matrix decompose, FFT)
  • Combining MPI process parallelism with OpenMP thread parallelism
  • Running HPC jobs with Slurm/PBS + mpirun
  • Debugging deadlocks and message mismatches
  • Parallel file I/O with MPI-IO

Workflow

1. Minimal MPI program
#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. Point-to-point
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);
}

Tagged messages: match tag and source for MPI_Recv.

3. Collectives
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);
CollectivePurpose
MPI_BcastOne-to-all
MPI_ScatterDistribute chunks
MPI_GatherCollect chunks
MPI_AllreduceReduce + broadcast result
MPI_BarrierSynchronization
MPI_AlltoallAll-to-all exchange
4. Non-blocking communication
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);

Overlap communication with computation to hide latency.

5. Subcommunicators
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 hybrid
#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

Bind ranks to sockets with --map-by ppr:2:socket.

7. Launching with hostfile
# 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);

Collective I/O for better performance:

MPI_File_write_at_all(fh, offset, buf, count, MPI_DOUBLE, MPI_STATUS_IGNORE);
9. Performance issues
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

Common Problems

SymptomCauseFix
Hang at MPI_RecvTag/source mismatchCheck Send/Recv pairing; use MPI_ANY_TAG debug
DeadlockCircular waitReorder comm pattern; use non-blocking
Wrong result in AllreduceWrong datatype/countVerify MPI_INT vs MPI_DOUBLE
Poor scalingRank 0 bottleneckDistribute I/O and aggregation
MPI_ERR_TRUNCATEReceive buffer too smallMatch send/recv counts
Hybrid oversubscriptionToo many threads×ranksOMP_NUM_THREADS = cores/ranks

Related Skills

  • skills/hpc/openmp — thread-level parallelism within MPI ranks
  • skills/hpc/rdma-verbs — low-latency interconnect under MPI
  • skills/allocators/numa-programming — bind ranks to NUMA nodes
  • skills/profilers/linux-perf — profile MPI rank hotspots
  • skills/debuggers/gdb — debug individual MPI processes
  • skills/compilers/gcc — MPI compiler wrapper flags

Comments

Markdown supported