#c #ubuntu #process #mpi #spawn
#c #ubuntu #процесс #mpi #спавн
Вопрос:
Я реализовал следующий код на 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(amp;argc, amp;argv);
MPI_Comm_rank(MPI_COMM_WORLD, amp;rank);
MPI_Comm_size(MPI_COMM_WORLD, amp;size);
if (rank == 0){
myFields = start(rank, size);
//for (int i = 0 ; i < myFields->hostNumber ; i ) printf("%dn",((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(amp;(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((amp;(myFields->hostNumber)), 1, MPI_INT, 0, 1000, MPI_COMM_WORLD, amp;status);
MPI_Get_count(amp;status, MPI_INT, amp;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 = %dn", myFields->hostNumber);
myFields->numberArray = (int *)malloc(sizeof(struct fields) * (myFields->hostNumber));
MPI_Recv((myFields->numberArray), (myFields-> hostNumber), MPI_INT, 0, 1001, MPI_COMM_WORLD, amp;status); //Why this is not running?
MPI_Get_count(amp;status, MPI_INT, amp;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("%dn",(*(myFields->numberArray)));
(myFields->numberArray) ;
}*/
/*for (int i = 0 ; i < myFields->hostNumber ; i ){
printf("%dn",((myFields->numberArray)[i]));
}*/
}
tmpNmb1 = ((myFields->hostNumber) / size);
tmpNmb2 = ((myFields->hostNumber) % size);
int row = (rank * tmpNmb1);
//printf("tmpNb1=%dn",tmpNmb1);
//printf("tmpNb2=%dn",tmpNmb2);
//printf("row=%dn",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, amp;status);
MPI_Get_count(amp;status, MPI_INT, amp;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] = %dn", 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] = %dn", i, finalArray[i]);
}
if ((tmpNmb2 != 0) amp;amp; (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] = %dn", 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 %dn", 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 Executionn");
printf("2) Type 2 For Exitn");
printf("Give your choice:");
scanf("%d",amp;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("%dn",((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",amp;host);
}
int *nmbArray = (int *)malloc(sizeof(nmbArray) * host);
for (int i = 0; i < host; i ){
printf("Give the %d number:", i);
scanf("%d", (amp;(nmbArray[i])));
}
myFields->hostNumber = host;
myFields->numberArray = amp;nmbArray[0];
//for (int i = 0 ; i < host ; i ) printf("%dn",((myFields->numberArray)[i]));
return myFields;
}
Теперь мне приходится повторно вызывать программу снова при каждом выходе. Поэтому я пытаюсь использовать MPI_Comm_Spawn. Но я не смог найти реализацию в Интернете и перешел по этой ссылке:
https://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node98.htm
Таким образом, mycode становится как (проект Exercise1):
#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(amp;argc, amp;argv);
MPI_Comm_rank(MPI_COMM_WORLD, amp;rank);
MPI_Comm_size(MPI_COMM_WORLD, amp;size);
MPI_Comm everyone; /* intercommunicator */
//MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_UNIVERSE_SIZE, amp;universe_sizep, amp;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("%dn",((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, amp;everyone, MPI_ERRCODES_IGNORE);
for (int i = 1; i < ((myFields->universeSize) - 1); i ){
MPI_Send(amp;(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 Executionn");
printf("2) Type 2 For Exitn");
printf("Give your choice:");
scanf("%d",amp;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("%dn",((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 structn");
MPI_Abort(MPI_COMM_WORLD, 0);
}
if (rank == 0){
//if (!flag) {
printf("This MPI does not support UNIVERSE_SIZE. How manyn processes total?n");
scanf("%d", amp;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",amp;host);
int *nmbArray = (int *)malloc(sizeof(nmbArray) * host);
for (int i = 0; i < host; i ){
printf("Give the %d number:", i);
scanf("%d", (amp;(nmbArray[i])));
}
myFields->hostNumber = host;
myFields->numberArray = amp;nmbArray[0];
myFields->universeSize = universe_size;
}
//for (int i = 0 ; i < host ; i ) printf("%dn",((myFields->numberArray)[i]));
return myFields;
}
И проект Exercise1_1:
#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(amp;argc, amp;argv);
MPI_Comm_rank(MPI_COMM_WORLD, amp;rank);
MPI_Comm parent;
MPI_Comm_get_parent(amp;parent);
MPI_Comm_remote_size(parent, amp;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((amp;(myFields->hostNumber)), 1, MPI_INT, 0, 1000, parent, amp;status);
MPI_Get_count(amp;status, MPI_INT, amp;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 = %dn", myFields->hostNumber);
myFields->numberArray = (int *)malloc(sizeof(struct fields) * (myFields->hostNumber));
MPI_Recv((myFields->numberArray), (myFields-> hostNumber), MPI_INT, 0, 1001, parent, amp;status);
MPI_Get_count(amp;status, MPI_INT, amp;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("%dn",(*(myFields->numberArray)));
(myFields->numberArray) ;
}*/
/*for (int i = 0 ; i < myFields->hostNumber ; i ){
printf("%dn",((myFields->numberArray)[i]));
}*/
//All other code are comments
MPI_Finalize();
return 0;
}
Проблема в том, что в первом случае я не могу использовать free(myFields), как показывает код, я получаю ошибку при MPI_Abort(). Освобождается ли это выделение при прерывании программы?
Во-вторых, я не могу запустить программу ни во втором случае, когда я использую MPI_spawn, ни в последнем.
Когда рабочие процессы инициализируются, имеют ли они ранг = 0 для любого указанного мной ранга?
Сообщение во втором случае отправляется от менеджера, но рабочие не отвечают. Консоль зависает.
Есть предложения?