MPI多处理器编程求助:基于Edges集合的动态通信实现
Hey Sarah, let's break this down step by step since you're new to MPI—no need to stress! I'll walk you through the core functions you need and a sample code to implement your requirement.
First, let's clarify your goal: Process 0 holds the Edges set {(0,4),(1,5)}, needs to send corresponding values to target processes, and also receive messages from other processes. Here's what you need to know:
核心MPI Functions You'll Use
These are the building blocks for your task, explained in plain terms:
1. Environment Setup & Cleanup
MPI_Init(&argc, &argv): Must be called first to initialize the MPI environment—think of it as turning on the MPI system.MPI_Finalize(): Call this last to shut down MPI properly, like turning off the system when you're done.
2. Get Process Info
MPI_Comm_rank(MPI_COMM_WORLD, &rank): Gets the unique ID (rank) of the current process. Process 0 will be your main process holding the Edges set.MPI_Comm_size(MPI_COMM_WORLD, &size): Tells you how many total processes are running—useful to check if your target processes (like 4 and 5) actually exist.
3. Point-to-Point Communication
MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm): Blocking send function. Process 0 uses this to send values to target processes (e.g., send0to process 4).MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status): Blocking receive function. Process 0 uses this to get messages from other processes; target processes use it to receive data from process 0.MPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status *status): Optional but handy for dynamic receiving—checks if there's a message waiting before callingMPI_Recv, which is useful if you don't know when other processes will send data.
Sample Code Implementation
Here's a working example that matches your requirement:
#include <stdio.h> #include <mpi.h> int main(int argc, char** argv) { int rank, size; // Initialize MPI environment MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (rank == 0) { // Process 0's Edges collection int edges[2][2] = {{0,4}, {1,5}}; int num_edges = 2; int received_data; MPI_Status status; // Send values to target processes for (int i = 0; i < num_edges; i++) { int value_to_send = edges[i][0]; int target_rank = edges[i][1]; // Make sure the target process exists if (target_rank < size) { MPI_Send(&value_to_send, 1, MPI_INT, target_rank, 0, MPI_COMM_WORLD); printf("Process 0 sent %d to Process %d\n", value_to_send, target_rank); } } // Receive responses from other processes for (int i = 0; i < num_edges; i++) { // Use MPI_ANY_SOURCE to accept messages from any process MPI_Recv(&received_data, 1, MPI_INT, MPI_ANY_SOURCE, 1, MPI_COMM_WORLD, &status); printf("Process 0 received %d from Process %d\n", received_data, status.MPI_SOURCE); } } else { // Other processes: receive from Process 0, then send a reply int received_value; MPI_Status status; // Receive message tagged 0 from Process 0 MPI_Recv(&received_value, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); printf("Process %d received %d from Process 0\n", rank, received_value); // Send a reply back to Process 0 (tagged 1 to distinguish) int reply_data = rank + received_value; MPI_Send(&reply_data, 1, MPI_INT, 0, 1, MPI_COMM_WORLD); } // Clean up MPI environment MPI_Finalize(); return 0; }
Key Notes
- Tag Usage: I used tag
0for messages from Process 0, and tag1for replies—this helps avoid mixing up different message types. - MPI_ANY_SOURCE: Process 0 uses this to accept messages from any process, which is perfect if you don't know exactly which processes will send data.
- Blocking vs Non-Blocking: The example uses blocking communication (simpler for beginners). If you need better performance or async operations later, you can switch to non-blocking functions like
MPI_IsendandMPI_Irecv, paired withMPI_Waitto complete the communication.
If you need to send the entire edge pair (both values) instead of a single integer, just adjust the count parameter to 2 and pass the edge array directly.
内容的提问来源于stack exchange,提问作者Sarah

