I implemented the following code on C:
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
struct fields{
int hostNumber;
int *numberArray;
};
struct fields *start(int, int);
struct fields *gatherData(int, int);
int main(int argc, char** argv) {
int rank, size, tmpNmb1, tmpNmb2,
notOrderedFlag = 0, tmpI = 0,
nbFinalArray, tmpRetrieveArray[3],
count, row1 = 0, col1 = 0;
struct fields *myFields;
MPI_Status status;
setbuf(stdout, NULL);
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (rank == 0){
myFields = start(rank, size);
//for (int i = 0 ; i < myFields->hostNumber ; i++) printf("%d\n",((myFields->numberArray)[i]));
if ((myFields->hostNumber) < size){
printf("Error!!! Number of Processes is more than number of Elements.\n");
MPI_Abort(MPI_COMM_WORLD, 0);
}
if (myFields->hostNumber < (2 * size)){
printf("Error!!! The Host of Numbers should be at least double of the number of Processes!!!\n");
MPI_Abort(MPI_COMM_WORLD, 0);
}
for (int i = 1; i < size; i++){
MPI_Send(&(myFields->hostNumber), 1, MPI_INT, i, 1000, MPI_COMM_WORLD);
MPI_Send(myFields->numberArray, myFields->hostNumber, MPI_INT, i, 1001, MPI_COMM_WORLD);
}
}
if (rank != 0){
myFields = (struct fields *)malloc(sizeof(struct fields));
if (myFields == NULL){
printf("Error while allocating memory for myFields structure!!!\n");
MPI_Abort(MPI_COMM_WORLD, 0);
}
MPI_Recv((&(myFields->hostNumber)), 1, MPI_INT, 0, 1000, MPI_COMM_WORLD, &status);
MPI_Get_count(&status, MPI_INT, &count);
//printf("Process %d received %d int(s) from Process %d with tag %d \n", rank, count, status.MPI_SOURCE, status.MPI_TAG);
//printf("number = %d\n", myFields->hostNumber);
myFields->numberArray = (int *)malloc(sizeof(struct fields) * (myFields->hostNumber));
MPI_Recv((myFields->numberArray), (myFields-> hostNumber), MPI_INT, 0, 1001, MPI_COMM_WORLD, &status); //Why this is not running?
MPI_Get_count(&status, MPI_INT, &count);
//printf("Process %d received %d int(s) from Process %d with tag %d \n", rank, count, status.MPI_SOURCE, status.MPI_TAG);
/*for (int i = 0 ; i < myFields->hostNumber ; i++){
printf("%d\n",(*(myFields->numberArray)));
(myFields->numberArray)++;
}*/
/*for (int i = 0 ; i < myFields->hostNumber ; i++){
printf("%d\n",((myFields->numberArray)[i]));
}*/
}
tmpNmb1 = ((myFields->hostNumber) / size);
tmpNmb2 = ((myFields->hostNumber) % size);
int row = (rank * tmpNmb1);
//printf("tmpNb1=%d\n",tmpNmb1);
//printf("tmpNb2=%d\n",tmpNmb2);
//printf("row=%d\n",row);
if (tmpNmb2 == 0){
nbFinalArray = size;
}
else{
nbFinalArray = (size + 1);
}
int finalArray[nbFinalArray];
int retrieveArray[size - 1][3];
for (int i = row ; i < ((row + tmpNmb1) - 1); i++){
if (((myFields->numberArray)[i]) <= ((myFields->numberArray)[i+1])){
notOrderedFlag = 0; //Ordered
if (rank == 0) finalArray[rank] = myFields->numberArray[tmpNmb1 -1];
}
else{
notOrderedFlag = 1; // Not Ordered
tmpI = i;
break;
}
}
if (notOrderedFlag == 1){
if (rank == 0){
printf("From Proccess 0 - Position %d. The Array is not Ordered!\n", tmpI);
MPI_Abort(MPI_COMM_WORLD, 0);
}
else if (rank != 0){
int tmpArray[3] = {rank, notOrderedFlag, tmpI};
MPI_Send(tmpArray, 3, MPI_INT, 0, 1000, MPI_COMM_WORLD); //wrong Array
}
}
if (rank == 0){
for (int i = 1; i < size ; i++){
MPI_Recv(tmpRetrieveArray, 3, MPI_INT, i, 1000, MPI_COMM_WORLD, &status);
MPI_Get_count(&status, MPI_INT, &count);
//printf("Process %d received %d int(s) from Process %d with tag %d \n", rank, count, status.MPI_SOURCE, status.MPI_TAG);
//for (int i = 0; i < 3; i++) printf("Array[%d] = %d\n", i, tmpRetrieveArray[i]);
for (int j = 0; j < 3; j ++){
retrieveArray[row1][col1] = tmpRetrieveArray[j];
col1++;
}
row1++;
col1 = 0;
}
row1 = col1 = 0;
/*for (int i = 0 ;i < (size-1);i++){
for (int j = 0;j<3;j++){
printf("aa = %d, ", retrieveArray[i][j]);
}
printf("\n");
}*/
}
if (rank != 0){
if (notOrderedFlag == 0){
int tmpArray[3] = {rank, notOrderedFlag, ((myFields->numberArray)[(row + tmpNmb1) - 1])};
MPI_Send(tmpArray, 3, MPI_INT, 0, 1000, MPI_COMM_WORLD); //Right Array
}
}
if (rank == 0){
for ( int row1 = 0; row1 < size; row1++ )
if (retrieveArray[row1][1] == 1){
printf("From Proccess %d - Position %d. The Array is not Ordered!\n", retrieveArray[row1][0], retrieveArray[row1][2]);
MPI_Abort(MPI_COMM_WORLD, 0);
}
else if (retrieveArray[row1][1] == 0){
finalArray[retrieveArray[row1][0]] = retrieveArray[row1][2];
}
//for (int i = 0 ; i < size; i ++) printf("finalArray[%d] = %d\n", i, finalArray[i]);
}
if ((tmpNmb2 != 0) && (rank == 0)){
for (int i = ((myFields->hostNumber) - tmpNmb2); i < ((myFields->hostNumber) - 1); i++){
if (((myFields->numberArray)[i]) > ((myFields->numberArray)[i+1])){
printf("From Proccess 0 - Position %d. The Array is not Ordered!\n", i);
MPI_Abort(MPI_COMM_WORLD, 0);
}
}
finalArray[nbFinalArray - 1] = myFields->numberArray[myFields->hostNumber - 1];
for (int i = 0 ; i < size; i ++) printf("finalArray[%d] = %d\n", i, finalArray[i]);
}
if (rank == 0){
for (int i = 0 ; i < (nbFinalArray -1); i++){
if (finalArray[i] > finalArray[i+1]){
printf("Final Array is NOT ORDRED. From Proccess 0 - Position %d\n", i);
MPI_Abort(MPI_COMM_WORLD, 0);
}
}
printf("The Array is Ordered!!!\n");
}
MPI_Finalize();
return 0;
}
struct fields *start(int rank, int size){
int input;
struct fields *myFields;
printf("1) Type 1 For Execution\n");
printf("2) Type 2 For Exit\n");
printf("Give your choice:");
scanf("%d",&input);
switch(input){
case 1:
myFields = gatherData(rank, size);
break;
case 2:
default:
//free(myFields);
MPI_Abort(MPI_COMM_WORLD, 0);
}
//for (int i = 0 ; i < myFields->hostNumber ; i++) printf("%d\n",((myFields->numberArray)[i]));
return myFields;
}
struct fields *gatherData(int rank, int size){
int host;
struct fields *myFields;
myFields = (struct fields *)malloc(sizeof(struct fields));
if (myFields == NULL){
printf("Error while alloction memory for myFields struct!!!\n");
MPI_Abort(MPI_COMM_WORLD, 0);
}
if (rank == 0){
printf("Give the host of the number to be checked if they are ordered:");
scanf("%d",&host);
}
int *nmbArray = (int *)malloc(sizeof(nmbArray) * host);
for (int i = 0; i < host; i++){
printf("Give the %d number:", i);
scanf("%d", (&(nmbArray[i])));
}
myFields->hostNumber = host;
myFields->numberArray = &nmbArray[0];
//for (int i = 0 ; i < host ; i++) printf("%d\n",((myFields->numberArray)[i]));
return myFields;
}
Now I have to repeatedly call the program again every time it exits. So I amtrying to use MPI_Comm_Spawn. But I couldn't find an implementation on the internet and followed this link: https://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node98.htm
So mycode becomes as (Exercise1 project):
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
struct fields{
int universeSize;
int hostNumber;
int *numberArray;
};
struct fields *start(int, int, int *, int);
struct fields *gatherData(int, int, int *, int);
int main(int argc, char** argv) {
int rank, size, universe_size,
*universe_sizep, flag;
char worker_program[200] = {'/','h','o','m','e','/','k','o','n','s','t','a','n','t','i','n','o','s',
'd','m','s','/','N','e','t','B','e','a','n','s','P','r','o','j','e','c','t','s',
'/','E','x','e','r','c','i','s','e','1','_','1','/','m','a','i','n'};
struct fields *myFields;
setbuf(stdout, NULL);
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm everyone; /* intercommunicator */
//MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_UNIVERSE_SIZE, &universe_sizep, &flag);
// while(1){
system("clear");
if (rank == 0){
if (size != 1){
printf("Error Manager Process should be only one!!!\n");
MPI_Abort(MPI_COMM_WORLD, 0);
}
myFields = start(rank, size, universe_sizep, flag);
//for (int i = 0 ; i < myFields->hostNumber ; i++) printf("%d\n",((myFields->numberArray)[i]));
if ((myFields->hostNumber) < ((myFields->universeSize) - 1)){
printf("Error!!! Number of Processes is more than number of Elements.\n");
MPI_Abort(MPI_COMM_WORLD, 0);
}
if (myFields->hostNumber < (2 * ((myFields->universeSize) - 1))){
printf("Error!!! The Host of Numbers should be at least double of the number of Processes!!!\n");
MPI_Abort(MPI_COMM_WORLD, 0);
}
MPI_Comm_spawn(worker_program, MPI_ARGV_NULL, ((myFields->universeSize)-1), MPI_INFO_NULL, 0,
MPI_COMM_SELF, &everyone, MPI_ERRCODES_IGNORE);
for (int i = 1; i < ((myFields->universeSize) - 1); i++){
MPI_Send(&(myFields->hostNumber), 1, MPI_INT, i, 1000, everyone);
MPI_Send(myFields->numberArray, myFields->hostNumber, MPI_INT, i, 1001, everyone);
}
}
// }
MPI_Finalize();
return 0;
}
struct fields *start(int rank,int size,int *universe_sizep,int flag){
int input;
struct fields *myFields;
printf("1) Type 1 For Execution\n");
printf("2) Type 2 For Exit\n");
printf("Give your choice:");
scanf("%d",&input);
switch(input){
case 1:
myFields = gatherData(rank, size, universe_sizep, flag);
break;
case 2:
default:
MPI_Abort(MPI_COMM_WORLD, 0);
}
//for (int i = 0 ; i < myFields->hostNumber ; i++) printf("%d\n",((myFields->numberArray)[i]));
return myFields;
}
struct fields *gatherData(int rank,int size,int *universe_sizep,int flag){
int host, universe_size;
struct fields *myFields;
myFields = (struct fields *)malloc(sizeof(struct fields));
if (myFields == NULL){
printf("Cannot allocate memory for myFields struct\n");
MPI_Abort(MPI_COMM_WORLD, 0);
}
if (rank == 0){
//if (!flag) {
printf("This MPI does not support UNIVERSE_SIZE. How many\n processes total?\n");
scanf("%d", &universe_size);
//} else universe_size = *universe_sizep;
if (universe_size == 1){
printf("No room to start workers!!!\n");
MPI_Abort(MPI_COMM_WORLD, 0);
}
printf("Give the host of the number to be checked if they are ordered:");
scanf("%d",&host);
int *nmbArray = (int *)malloc(sizeof(nmbArray) * host);
for (int i = 0; i < host; i++){
printf("Give the %d number:", i);
scanf("%d", (&(nmbArray[i])));
}
myFields->hostNumber = host;
myFields->numberArray = &nmbArray[0];
myFields->universeSize = universe_size;
}
//for (int i = 0 ; i < host ; i++) printf("%d\n",((myFields->numberArray)[i]));
return myFields;
}
And Exercise1_1 Project:
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
struct fields{
int hostNumber;
int *numberArray;
};
int main(int argc, char** argv) {
int rank, remote_size, tmpNmb1, tmpNmb2,
notOrderedFlag = 0, tmpI = 0,
nbFinalArray, tmpRetrieveArray[3],
count, row1 = 0, col1 = 0;
struct fields *myFields;
MPI_Status status;
setbuf(stdout, NULL);
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm parent;
MPI_Comm_get_parent(&parent);
MPI_Comm_remote_size(parent, &remote_size);
if (rank == 0){
if (parent == MPI_COMM_NULL){
printf("Error!!! while getting Parent Comuniacator.\n");
MPI_Abort(MPI_COMM_WORLD, 0);
}
if (remote_size != 1){
printf("Error Manager - Parent Process should be only one!!!\n");
MPI_Abort(MPI_COMM_WORLD, 0);
}
}
if (rank == 0){
myFields = (struct fields *)malloc(sizeof(struct fields));
if (myFields == NULL){
printf("Error while allocating memory for myFields structure!!!\n");
MPI_Abort(MPI_COMM_WORLD, 0);
}
MPI_Recv((&(myFields->hostNumber)), 1, MPI_INT, 0, 1000, parent, &status);
MPI_Get_count(&status, MPI_INT, &count);
printf("Process %d received %d int(s) from Process %d with tag %d \n", rank, count, status.MPI_SOURCE, status.MPI_TAG);
printf("number = %d\n", myFields->hostNumber);
myFields->numberArray = (int *)malloc(sizeof(struct fields) * (myFields->hostNumber));
MPI_Recv((myFields->numberArray), (myFields-> hostNumber), MPI_INT, 0, 1001, parent, &status);
MPI_Get_count(&status, MPI_INT, &count);
//printf("Process %d received %d int(s) from Process %d with tag %d \n", rank, count, status.MPI_SOURCE, status.MPI_TAG);
/*for (int i = 0 ; i < myFields->hostNumber ; i++){
printf("%d\n",(*(myFields->numberArray)));
(myFields->numberArray)++;
}*/
/*for (int i = 0 ; i < myFields->hostNumber ; i++){
printf("%d\n",((myFields->numberArray)[i]));
}*/
//All other code are comments
MPI_Finalize();
return 0;
}
The problem is that at the first case I can't use free(myFields), as the code shows, I get error when MPI_Abort(). Is this allocation deallocated when the program Abort? Second I can't make the program run either at the seconde case when I use MPI_spawn nor at the last one. When The worker processes are initialized do they have rank = 0 to whatever rank i specify? The mesage at the second case is being send from manager but the workers does not respond. The console freezes.
Any suggestion?