MPI_Finalize() doesn't finalize - c

#include <stdio.h>
#include <math.h>
#include <mpi.h>
int main(int argc, char *argv[])
{
int i, done = 0, n;
double PI25DT = 3.141592653589793238462643;
double pi, tmp, h, sum, x;
int numprocs, rank;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (numprocs < 1)
printf("numprocs = %d, should be run with numprocs > 1\n", numprocs);
else {
while (!done)
{
if (rank == 0) {
printf("Enter the number of intervals: (0 quits) \n");
scanf("%d",&n);
}
if (n == 0) break;
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
h = 1.0 / (double) n;
sum = 0.0;
for (i = 1 + rank; i <= n; i+=numprocs) {
x = h * ((double)i - 0.5);
sum += 4.0 / (1.0 + x*x);
}
MPI_Reduce(&sum, &tmp, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
if (rank == 0) {
pi = h * tmp;
printf("pi is approximately %.16f, Error is %.16f\n", pi, fabs(pi - PI25DT));
}
}
}
MPI_Finalize();
}
I run this program with number of processes = 10 and after typing 0 in scanf("%d", &n); the program doesn't seem to finalize and I have to close it with Ctrl+C.
10 total processes killed (some possibly by mpirun during cleanup)
mpirun: clean termination accomplished
Appears in console after killing process.

Well, sure. Look at what's going on here:
if (rank == 0) {
printf("Enter the number of intervals: (0 quits) \n");
scanf("%d",&n);
}
if (n == 0) break;
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
If you enter '0' on rank 0, then rank 0 breaks, but all the other ranks have whatever they had in n last time around (or, in the case of the first iteration, whatever random stuff was in that memory location). So ranks 1-(N-1) enter the MPI_Bcast, patiently waiting to participate in a broadcast to find out what n is, and meanwhile rank 0 has exited the loop and is sitting at MPI_Finalize wondering where everyone else is.
You just need to flip those lines:
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (n == 0) break;
Now everyone decides whether or not to break out of the loop at the same time.

you have a endless while loop, so MPI_Finalize() can't execute.

Related

how can i run MPI program in windows

I tried running it with microsoft MPI but its not generating desired output.
#include <stdio.h>
#include <math.h>
#include "mpi.h"
double function(double x) {
// Define the function to be integrated here
return x * sin(x);
}
int main(int argc, char *argv[]) {
double a, b, h, sum, x;
int n, p, rank, size, i;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (rank == 0) {
printf("Enter the number of subintervals (n): ");
scanf("%d", &n);
printf("Enter the number of processes (p): ");
scanf("%d", &p);
}
// Broadcast the inputs to all processes
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&p, 1, MPI_INT, 0, MPI_COMM_WORLD);
a = 0.0;
b = 1.0;
h = (b - a) / n;
sum = 0.0;
// Divide the work among the processes
int interval_per_process = n / p;
int start = rank * interval_per_process;
int end = (rank + 1) * interval_per_process - 1;
for (i = start; i <= end; i++) {
x = a + h * (i + 0.5);
sum = sum + function(x);
}
sum = sum * h;
// Reduce the results from all processes to process 0
double global_sum;
MPI_Reduce(&sum, &global_sum, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
if (rank == 0) {
printf("The value of the integral is %.6lf\n", global_sum);
}
MPI_Finalize();
return 0;
}
So I need output like : It should ask for subintervals and processes and then give the final result i.e answer of integration using the midpoint rule.
But instead when i run it displays nohting and if enter any number it skips the scanner part and directly produce the output
I need a compiler

Caught signal 11 (Segmentation fault: address not mapped to object at address 0xff00000107)

Im practising in parallel programming using MPI and i developed a programm that is calculating the average and how many numbers of the array are greater or fewer than the average. Unfortunately when im trying to run it on linux ubuntu system i get this *Caught signal 11 (Segmentation fault: address not mapped to object at address 0xff00000107), backtrace(tid: 5699).
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
int main(int argc, char** argv){
int p, plithos, i, k, count_max,count_min, sunexeia;
int *pinakas;
int *final_res;
int loc_matrix[100];
int loc_num;
int my_rank;
int root, local_sum, sum, j, source;
int tag1=50;
int tag2=60;
int tag3=70;
int tag4=80;
float average;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &p);
if (my_rank == 0) {
printf("please give the size of the array: ");
scanf("%d", &plithos);
pinakas = (int *) malloc(plithos * sizeof(int));
for (i = 0; i < plithos; i++) {
printf("Give the %d number: ", i);
scanf("%d", &pinakas[i]);
}
}
root = 0;
MPI_Bcast(&plithos, 1, MPI_INT, root, MPI_COMM_WORLD); // here we are sending the size of the array to the processors
loc_num = plithos / p;
root = 0;
MPI_Scatter(&pinakas, loc_num, MPI_INT, &loc_matrix, loc_num, MPI_INT, root, MPI_COMM_WORLD); // here we are sending the amount of tasks that every processor must have
local_sum=0; // here all processors will calculate their sums
if (my_rank == 0) {
int start = 0;
int end = loc_num;
for (i = start; i < end; i++){
local_sum += pinakas[i];
}
}
else{
int start = my_rank * loc_num;
int end = my_rank + loc_num;
for (i = start; i < end; i++){
local_sum += pinakas[i];
}
}
MPI_Reduce(&local_sum, &sum, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); //here with the reduce we are caclulating all the sums from all processors
if (my_rank == 0) { // processor 0 finds the average
average = (double)sum / plithos;
printf("The average is: %f\n", average);
}
root = 0;
MPI_Bcast(&average, 1, MPI_FLOAT, root, MPI_COMM_WORLD); //edo stelnoume tin mesi timi stis upoloipes diergasies
if (my_rank = 0){ //edo h diergasia 0 tha upologisei posa stoixeia exoun min kai max > tou average
for(i=0; i<plithos; i++){
if(pinakas[i]> average){
count_max = count_max +1;
}
if(pinakas[i]< average){
count_min = count_min +1;
}
}
printf("To plithos ton stoixeion pou exoun megaluteri timi apo tin mesi timi einai: %d", count_max);
printf("To plithos ton stoixeion pou exoun mikroteri timi apo tin mesi timi einai: %d", count_min);
}
MPI_Finalize();
}

MPI sum of array receive working for only one rank

I am trying to find the sum of an array of length 100 elements using MPI, under the restrictions of only using MPI_Send and MPI_receive , the code that I have written finds the sum of each processor but during the re-send to the main processor(rank=0) my code only receives from one processor
My Code
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include "mpi.h"
#include "math.h"
int val = 1;
int main(int argc, char* argv[]) {
int my_rank;
int p;
int ierr;
int i;
int a[100];
int q=0;
for (i = 0; i <100; i++)
{
a[i] = i+1;
}
int send,recv;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &p);
int part = 100 /(p-1);
if (my_rank == 0)
{
for (i = 1; i < p; i++)
{
send = part * (i-1);
MPI_Send(&send, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
}
}
else
{
MPI_Recv(&recv, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
for (i = recv; i < recv + part; i++)
{
val = val+a[i];
}
printf("%d\n", val);
MPI_Send(&val, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
}
if (my_rank == 0)
{
MPI_Recv(&val, 1, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status);
printf("%d", val);
q = q + val;
}
MPI_Finalize();
if (my_rank == 0)
{
printf("The output is %d\n", q);
}
return 0;
}
My output
where am i going wrong
Because you only recieve the result from one process. To recieve all results, iterate over process ranks:
if (my_rank == 0)
{
for (rank = 1; rank < proc_cnt; rank++)
{
MPI_Recv(&val, 1, MPI_INT, rank, 0, MPI_COMM_WORLD, &status);
printf("value of rank %d is %d", rank, val);
q = q + val;
}
}
Ordinarily, this a bad practice and may lead to deadlocks. Use mpi_gather() if allowed.

Passing submatrices from master to slaves MPI

I'm trying to learn MPI and I've run into the following problem in one of my courses:
Consider a matrix A of dimensions n * n in which each element is an integer. Given 2 pair of indices (i1,j1) and (i2,j2) find the submatrix of such dimensions in matrix A for which it's elements sum is maximum.
I'd like some help on how to pass the submatrices to the processes. Should I calculate first how many submatrices (s) are in the matrix and send to each process N/s? How would I send the submatrices?
Some skeleton code I wrote:
#include<mpi.h>
#include<stdio.h>
#include<math.h>
#include<assert.h>
#include<iostream>
using namespace std;
#pragma comment (lib, "msmpi.lib")
enum CommunicationTag
{
COMM_TAG_MASTER_SEND_TASK,
COMM_TAG_MASTER_SEND_TERMINATE,
COMM_TAG_SLAVE_SEND_RESULT,
};
void print_matrix(int mat[10][10], int n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
//0. Init part, finding rank and number of processes
int numprocs, rank, rc;
rc = MPI_Init(&argc, &argv);
if (rc != MPI_SUCCESS) {
printf("Error starting MPI program. Terminating \n");
MPI_Abort(MPI_COMM_WORLD, rc);
}
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
printf("I'm rank %d. Num procs %d\n", rank, numprocs); fflush(stdout);
//1. different machine code
if (rank == 0)
{
int n;
scanf("%d", &n);
int i1, i2, j1, j2;
scanf("%d%d%d%d", &i1, &i2, &j1, &j2);
int mat[10][10];
//init data
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
mat[i][j] = (rand() % 100) - 50; //init random between -50 and 49
}
print_matrix(mat, n);
//here; how do I pass the submatrices to the processes?
for (int i = 1; i < numprocs; i++) {
MPI_Send(&i1, 1, MPI_INT, i, COMM_TAG_MASTER_SEND_TASK, MPI_COMM_WORLD);
MPI_Send(&i2, 1, MPI_INT, i, COMM_TAG_MASTER_SEND_TASK, MPI_COMM_WORLD);
MPI_Send(&j1, 1, MPI_INT, i, COMM_TAG_MASTER_SEND_TASK, MPI_COMM_WORLD);
MPI_Send(&j2, 1, MPI_INT, i, COMM_TAG_MASTER_SEND_TASK, MPI_COMM_WORLD);
//here; how do I pass the submatrices to the processes?
}
}
else {
//if slave ...
}
system("Pause");
}
The first step is to stop thinking about how to use MPI_Send(). The basic solution is to use MPI_Bcast() to transmit A to all the MPI processes.
Then divide the work up (no need to communicate for this, the same dividing logic can run in each process). Compute the sums within each MPI process, and collect them in the main process using MPI_Gather(). Choose the largest and you're done.
It really only requires two MPI operations: Bcast to distribute the input data to all processes, and Gather to centralize the results.
Note that all MPI processes need to execute the collective operations together in lockstep. You only need if (rank == 0) to know which process should load the matrix and analyze the Gathered results.

For some reason MPI_Waitall gets stuck (in a deadlock I believe) when I test my program with big numbers

For some reason MPI_Waitall is waiting forever when I enter 10000 as the length for the sequence. Basically I create 4 lists of length n/4 where in this case n is 10000 and I an using non-blocking send so my process 0 does not wait for each list to be sent separately as they do not share any values so they are not overwritten.
Keep in mind that the program works with smaller numbers like 1000 or 100 but I am not sure why it does not work with 10000+.
Here is my code:
#include "ore_header.h"
int main(int argc, char** argv) {
srand(time(NULL));
int my_rank, p;
void generate_sequence(int *arr, int n);
int subsequence_check(int *arr,int n, int m);
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
int total;
int length;
int flag;
int seq_length;
MPI_Status stats[p];
MPI_Request reqs[p];
int p_length=0;
int *buf[p];
if (my_rank == 0) {
printf("Enter length and sequence length\n");
scanf("%d %d",&length, &seq_length);
p_length = length / p;
for (int i = 0; i < p; i++) {
buf[i] = (int*)malloc(p_length*sizeof(int));
generate_sequence(buf[i], p_length);
MPI_Isend(buf[i], p_length, MPI_INT, i, 0, MPI_COMM_WORLD, &reqs[i]);
printf("Data sent to process %d\n", i);
}
MPI_Waitall(p, reqs, stats); //Program wont go past this line
printf("\n\n Data sent to all processes \n\n");
}
MPI_Bcast(&p_length, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&seq_length, 1, MPI_INT, 0, MPI_COMM_WORLD);
buf[my_rank] = (int*)malloc(p_length*sizeof(int));
MPI_Recv(buf[my_rank], p_length, MPI_INT, 0, 0, MPI_COMM_WORLD, &stats[my_rank]);
printf("\nData received on process: %d Length: %d\n",my_rank,p_length);
//for (int i = 0; i < p_length; i++) {
// printf("%d",buf[my_rank][i]);
//}
//printf("\n");
total = subsequence_check(buf[my_rank],p_length,seq_length);
printf("\nI am process: %d\nTotal: %d\n",my_rank,total);
MPI_Finalize();
return (0);
}

Resources