Ошибка при использовании производных типов данных MPI
bool isComposite(int num) {
if (num < 2) return false;
for (int i = 2; i <= sqrt(num); ++i) {
if (num % i == 0) return true;
}
return false;
}
int main(int argc, char** argv) {
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
srand(time(0));
int rows_per_proc = M / size;
int extra_rows = M % size;
int* sendcounts = new int[size];
int* displs = new int[size];
vector<int> matrix(M * N);
vector<int> local_data;
if (rank == 0) {
for (int i = 0; i < M * N; ++i) {
matrix[i] = rand() % 100;
}
cout << "Original Matrix:" << endl;
for (int i = 0; i < M; ++i) {
for (int j = 0; j < N; ++j) {
cout << matrix[i * N + j] << " ";
}
cout << endl;
}
}
// Расчет количества и смещения для блочного распределения данных
for (int i = 0; i < size; ++i) {
sendcounts[i] = (i < extra_rows) ? (rows_per_proc + 1) : rows_per_proc;
displs[i] = (i > 0) ? (displs[i - 1] + sendcounts[i - 1]) : 0;
}
// Создание производного типа данных MPI для блока
MPI_Datatype block_type;
MPI_Type_vector(sendcounts[rank], N, N * size, MPI_INT, &block_type);
MPI_Type_create_resized(block_type, 0, N * sizeof(int), &block_type);
MPI_Type_commit(&block_type);
local_data.resize(sendcounts[rank] * N);
MPI_Scatterv(matrix.data(), sendcounts, displs, block_type, local_data.data(), sendcounts[rank] * N, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Type_free(&block_type);
cout << "Process " << rank << " - local data:" << endl;
for (int i = 0; i < sendcounts[rank] * N; ++i) {
cout << local_data[i] << " ";
if ((i + 1) % N == 0) cout << endl;
}
double start_time = MPI_Wtime();
// Обработка локальных данных
for (int i = 0; i < sendcounts[rank] * N; ++i) {
if (isComposite(local_data[i])) {
local_data[i] = 0;
}
}
double end_time = MPI_Wtime();
MPI_Gatherv(local_data.data(), sendcounts[rank] * N, MPI_INT, matrix.data(), sendcounts, displs, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0) {
cout << "Modified Matrix:" << endl;
for (int i = 0; i < M; ++i) {
for (int j = 0; j < N; ++j) {
cout << matrix[i * N + j] << " ";
}
cout << endl;
}
cout << "Execution time for " << size << " processes: " << (end_time - start_time) * 1000 << " sec." << endl;
}
delete[] sendcounts;
delete[] displs;
MPI_Finalize();
return 0;
}
При запуске программы с 4 процессами выводиться ошибка: Fatal error in MPI_Scatterv: Message truncated, error stack: MPI_Scatterv(sbuf=0x00000270885386F0, scnts=0x000002708853D600, displs=0x000002708853DA10, dtype=USER, rbuf=0x0000027088520D40, rcount=16, MPI_INT, root=0, MPI_COMM_WORLD) failed Message truncated; 64 bytes received but buffer size is 64
Как её исправить? Она появилась после того, как я добавил строки
MPI_Datatype block_type;
MPI_Type_vector(sendcounts[rank], N, N * size, MPI_INT, &block_type);
MPI_Type_create_resized(block_type, 0, N * sizeof(int), &block_type);
MPI_Type_commit(&block_type);
local_data.resize(sendcounts[rank] * N);
MPI_Scatterv(matrix.data(), sendcounts, displs, block_type, local_data.data(), sendcounts[rank] * N, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Type_free(&block_type);