Good time of day!

Tell me where the jambs in the program. I solve this problem in C ++ using MPI (note that you cannot use collective exchanges):

A Cro-Magnon tribe hunts a cave bear, who sleeps in its lair in one of the caves. To do this, they are separated and begin to look into all the caves in a row until one of them finds a bear. Since the screams can wake the bear ahead of time, the bear finder finds each of his comrades and in a whisper informs him that the bear has been found. Write a program that simulates the behavior of the tribe, excluding collective exchanges.

The problem is that nothing happens in the console. More precisely, the array is created, filled with elements and displayed on the screen, but the MPI functions themselves do not work out - the cursor simply blinks.

I will say in advance that I tried to use MPI_Isend and MPI_Wait, but to no avail Here is my govnokod)):

введите сюда код #include<mpi.h> #include<iostream> #include<cstdlib> #include<stdio.h> #define TegN 1 #define TegAreaBear 2 #define TegAreaBearTail 3 #define TegBearPositionNul 4 #define TegBearPosition 5 using namespace std; // Определяем медведя в одну из пещер // элементы = -1 - это пустые пещеры // элементы = 1 - это искомая пещера void BearSleep (int* AreaBear, int N) { for (int i=0; i<N; i++) { AreaBear[i] = -1; } int k = rand() %N; AreaBear[k] = 1; for (int i=0; i<N; i++) { cout << AreaBear[i] << " "; } cout << endl; } // Ищем пещеру с медведем. Если элемент равен 1, то возвращаем номер пещеры int search(int* arr, int n) { for (int i=0; i<n; i++) { if (arr[i] == 1) return i; } return -1; } int main (int argc, char **argv) { // N - число пещер, size - количество процессов (кроманьонцев), rank - номер процесса int size, rank; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (rank == 0) { int N; cout << "Ukazite kolichestvo peshcher" << endl; cin >> N; cout << "Kolichestvo peshcher = " << N << endl; // Инициализируем территорию поиска - массив пещер int* AreaBear = new int[N]; // Определяем медведя в одну из пещер BearSleep(AreaBear, N); // Нулевому процессу отдаем его часть массива - голову массива int* AreaBearHead = new int[N/size]; for (int i=0; i<N/size; i++) { AreaBearHead[i] = AreaBear[i]; } //Остальным процессам будем передавать хвост массива int* AreaBearTail = new int[N - N/size]; for (int i=0; i<N - N/size; i++) { AreaBearTail[i] = AreaBear[i+N/size]; } // Передаем процессам размер N for (int r=1; r<size; r++) { MPI_Send(&N, 1, MPI_INT, r, TegN, MPI_COMM_WORLD); } // Передаем процессам массив-хвост for (int r=1; r<size; r++) { MPI_Send(&AreaBearTail[r*N/size], N/size, MPI_INT, r, TegAreaBearTail, MPI_COMM_WORLD); } // На нулевом процессе ищем пещеру в массиве-голове int BearPositionNul = search(AreaBearHead, N/size); // Если нашли, то передаем процессам индекс пещеры // и пишем сообщение, что нулевой процесс теперь знает, где медведь if (BearPositionNul >= 0) { for (int r=1; r<size; r++) { MPI_Send(&BearPositionNul, 1, MPI_INT, r, TegBearPositionNul, MPI_COMM_WORLD); } printf ("\n Now hunter %3d know where bear is slepping. This cave %3d", rank, BearPositionNul); } // Если индекс пещеры обнаружен на другом процессе, то принимаем информацию от него int BearPosition; for (int i=1; i<size; i++) { MPI_Recv(&BearPosition, 1, MPI_INT, MPI_ANY_SOURCE, TegBearPosition, MPI_COMM_WORLD, &status); printf ("\n Now hunter %3d know where bear is slepping. This cave %3d", rank, BearPosition); } } else { int N; // Принимаем размер массива N от нулевого процесса MPI_Recv(&N, 1, MPI_INT, 0, TegN, MPI_COMM_WORLD, &status); // Инициализируем массив-приемник // И принимаем массив-хвост из нулевого процесса int* AreaBearTail = new int[N/size];; MPI_Recv(AreaBearTail, N/size, MPI_INT, 0, TegAreaBearTail, MPI_COMM_WORLD, &status); // Покажем эти части for (int i=0; i<N/size; i++) { cout << AreaBearTail[i] << " "; } // Каждый процесс ищет пещеру на своем участке int BearPosition = search(AreaBearTail, N/size); // Если пещера найдена, то отправляем индекс всем процессам, кроме себя // Процессы осуществляют прием сообщения if (BearPosition >= 0) { // от нулевого процесса до текущего for (int j=0; j<rank; j++) { MPI_Send(&BearPosition, 1, MPI_INT, j, TegBearPosition, MPI_COMM_WORLD); MPI_Recv(&BearPosition, 1, MPI_INT, rank, TegBearPosition, MPI_COMM_WORLD, &status); } // с послетекущего до последнего for (int j=rank+1; j<size; j++) { MPI_Send(&BearPosition, 1, MPI_INT, j, TegBearPosition, MPI_COMM_WORLD); MPI_Recv(&BearPosition, 1, MPI_INT, rank, TegBearPosition, MPI_COMM_WORLD, &status); } // Все процессы с первого сообщают, что они знают, где медведь for (rank=1; rank<size; rank++) { printf ("\n Now hunter %3d know where bear is slepping. This cave %3d", rank, BearPosition); } } // Принимаем сообщение от нулевого процесса, что он нашел пещеру с медведем int BearPositionNul; MPI_Recv(&BearPositionNul, 1, MPI_INT, 0, TegBearPositionNul, MPI_COMM_WORLD, &status); printf ("\n Now hunter %3d know where bear is slepping. This cave %3d", rank, BearPositionNul); } MPI_Finalize(); system("pause"); return 0; } 

ADDED A REDUCED CODE FOR DEBUGGING I decided to go through the steps, gradually putting everything else on it. In it, the zero process transfers the size of the array, the array itself in parts and the result of the search, the rest all accept it. If the zero process is found, it displays a message. The rest of the processes should output the same message, but they do not.

 #include <stdio.h> #include "mpi.h" #include <iostream> #include "stdafx.h" #define TegN 1 #define TegAreaBear 2 #define TegAreaBearTail 3 #define TegBearPositionNul 4 #define TegBearPosition 5 using namespace std; // Все пустые пещеры = минус единица, искомая пещера = +1 void BearSleep (int* AreaBear, int N) { for (int i=0; i<N; i++) { AreaBear[i] = -1; } // srand(time(NULL)); int k = rand() %N; // Рандомно выбираем номер пещеры AreaBear[k] = 1; // И помечаем эту пещеру единицей // Выводим массив пещер на экран for (int i=0; i<N; i++) { cout << AreaBear[i] << " "; } cout << endl; } // Функция поиска пещеры int search(int* SearchMishu, int n) { for (int i=0; i<n; i++) { if (SearchMishu[i] == 1) return i; } return -1; } void main (int argc, char **argv) { int N, N1, size, rank; // Количество пещер, количество кроманьонцев, номер кроманьонца int BearPosition, BearPosition1; int* AreaBearRank; int* AreaBearRank1; MPI_Status status, st, draf; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { cout << "Ukazite kolichestvo peshcher" << endl; cin >> N; cout << "Kolichestvo peshcher = " << N << endl; int* AreaBear = new int[N]; //Массив - количество пещер BearSleep(AreaBear, N); AreaBearRank = new int[N/size + N%size]; for (int i=0; i<(N/size+N%size); i++) { AreaBearRank[i] = AreaBear[i]; } for (int i=0; i<N/size+N%size; i++) { cout << "Rank number" << rank << " Elem:" << AreaBearRank[i] << " "; cout << endl; } for (int i=1; i<size; i++) { MPI_Send(&N, 1, MPI_INT, i, TegN, MPI_COMM_WORLD); } for (int i=1; i<size; i++) { MPI_Send(&AreaBear[i*N/size+N%size], N/size, MPI_INT, i, TegAreaBear, MPI_COMM_WORLD); } BearPosition = search(AreaBearRank, N/size + N%size); if (BearPosition >= 0) { cout << "I am " << rank << " know the number. This is " << BearPosition << endl; for (int i=1; i<size; i++) { MPI_Send(&BearPosition, 1, MPI_INT, i, TegBearPosition, MPI_COMM_WORLD); } } } if (rank>0) { MPI_Recv(&N1, 1, MPI_INT, 0, TegN, MPI_COMM_WORLD, &status); AreaBearRank1 = new int[N1/size]; MPI_Recv(AreaBearRank1, N1/size, MPI_INT, 0, TegAreaBear, MPI_COMM_WORLD, &st); for (int i=0; i<N1/size; i++) { cout << "Rank number" << rank << " Elem:" << AreaBearRank1[i] << " "; cout << endl; } MPI_Recv(&BearPosition1, 1, MPI_INT, rank, TegBearPosition, MPI_COMM_WORLD, &draf); if (BearPosition1 >= 0) { cout << "I am " << rank << " know the number. This is " << BearPosition1 << endl; } } MPI_Finalize(); system("pause"); } 

CONCLUSION TO ERROR

 Ukazite kolichestvo peshcher 13 Kolichestvo peshcher = 13 -1 -1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 Rank number0 Elem:-1 Rank number0 Elem:-1 Rank number0 Elem:1 Rank number0 Elem:-1 I am 0 know the number. This is 2 Rank number3 Elem:-1 Rank number2 Elem:-1 Rank number1 Elem:-1 Rank number3 Elem:-1 Rank number2 Elem:-1 Rank number1 Elem:-1 Rank number3 Elem:-1 Rank number2 Elem:-1 Rank number1 Elem:-1 

    1 answer 1

    You have the wrong order of calls MPI_Send and MPI_Recv in root and non-root processes. It must be reversed. If the root is send-receive, then non-root should be receive-send. Or vice versa.

    • Do you mean the last three lines in the else block? Or the principle of construction: MPI_Send 1, MPI_Send 2, MPI_Send 3 in zero, MPI_Recv 1, MPI_Recv 2, MPI_Recv 3 in non-root (digit is a type of information block)? - Arthur
    • I mean MPI_Send(&BearPosition ... pair calls MPI_Send(&BearPosition ... and MPI_Recv(&BearPosition ... - Igor
    • got it I'll think about how to fix it. While I commented out these lines, I left the transfer of the size of the array and the array itself to zero, the reception of the size of the array and the array itself, and the output of the array elements to the screen in the root. The console also displays nothing. When closing the console, it manages to give the message: unable to read the cmd header on the left child context. Other MPI error, error stack: ReadFailed (1317) and then abracadabra - Arthur
    • No one has any thoughts about this error? - Arthur
    • @ Arthur add to the question all that is displayed in the console - Igor