У меня проблема с моим кодом MPI, он зависает при запуске кода на несколько узлов. Это успешно завершается при запуске на один узел. Я не уверен, как отладить это. Может кто-нибудь помочь мне отладить эту проблему?
Использование программы:
mpicc -o string strin.cpp
mpirun -np 4 -npernode 2 -hostfile hosts ./string 12 0.1 0.9 10 2
Мой код:
#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
int main ( int argc, char **argv )
{
float *y, *yold;
float *v, *vold;
int nprocs, myid;
FILE *f = NULL;
MPI_Status status;
int namelen;
char processor_name[MPI_MAX_PROCESSOR_NAME];// const int NUM_MASSES = 1000;
// const float Ktension = 0.1;
// const float Kdamping = 0.9;
// const float duration = 10.0;
#if 0
if ( argc != 5 ) {
std::cout << "usage: " << argv[0] << " NUM_MASSES durationInSecs Ktension Kdamping\n";
return 2;
}
#endif
int NUM_MASSES = atoi ( argv[1] );
float duration = atof ( argv[2] );
float Ktension = atof ( argv[3] );
float Kdamping = atof ( argv[4] );
const int PICKUP_POS = NUM_MASSES / 7; // change this for diff harmonics
const int OVERSAMPLING = 16; // run sim at this multiple of audio sampling rate
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
MPI_Get_processor_name(processor_name, &namelen);
// open output file
if (myid == 0) {
f = fopen ( "rstring.raw", "wb" );
if (!f) {
std::cout << "can't open output file\n";
return 1;
}
}
// allocate displacement and velocity arrays
y = new float[NUM_MASSES];
yold = new float[NUM_MASSES];
v = new float[NUM_MASSES];
// initialize displacements (pluck it!) and velocities
for (int i = 0; i < NUM_MASSES; i++ ) {
v[i] = 0.0f;
yold[i] = y[i] = 0.0f;
if (i == NUM_MASSES/2 )
yold[i] = 1.0; // impulse at string center
}
// Broadcast data
//MPI_Bcast(y, NUM_MASSES, MPI_FLOAT, 0, MPI_COMM_WORLD);
//MPI_Bcast(yold, NUM_MASSES, MPI_FLOAT, 0, MPI_COMM_WORLD);
//MPI_Bcast(v, NUM_MASSES, MPI_FLOAT, 0, MPI_COMM_WORLD);
//int numIters = duration * 44100 * OVERSAMPLING;
int numIters = atoi( argv[5] );
for ( int t = 0; t < numIters; t++ ) {
// for each mass element
float sum = 0;
float gsum = 0;
int i_start;
int i_end ;
i_start = myid * (NUM_MASSES/nprocs);
i_end = i_start + (NUM_MASSES/nprocs);
for ( int i = i_start; i < i_end; i++ ) {
if ( i == 0 || i == NUM_MASSES-1 ) {
} else {
float accel = Ktension * (yold[i+1] + yold[i-1] - 2*yold[i]);
v[i] += accel;
v[i] *= Kdamping;
y[i] = yold[i] + v[i];
sum += y[i];
}
}
MPI_Reduce(&sum, &gsum, 1, MPI_FLOAT, MPI_SUM, 0, MPI_COMM_WORLD);
float *tmp = y;
y = yold;
yold = tmp;if (myid == 0) {
//printf("%f\n", gsum);
if ( t % OVERSAMPLING == 0 ) {
fwrite ( &gsum, sizeof(float), 1, f );
}
}
}
if (myid == 0) {
fclose ( f );
}
MPI_Finalize();
}
Если у вас есть возможность сделать это, вы можете попробовать запустить приложение в параллельном отладчике (например, Totalview).
В противном случае, когда программа зависает, вы можете подключить свободно доступный последовательный отладчик (например, GDB) к одному процессу за раз, чтобы увидеть, где может находиться потенциальная проблема.
Я полагаю, вы получаете сообщение, которое не отправлено ни одним узлом. Если каждый узел сначала попытается получить сообщение, какой узел отправит его?
Вы можете изменить программу, например, if id == 0 send(msg) else receive(&msg)
и попробуйте использовать таймауты.
Напишите на листе бумаги, как это работает и как взаимодействуют узлы, и вы увидите, в чем проблема.
Я наконец нашел ответ из списка рассылки OpenMPI. Я думаю, что проблема в том, как мои хосты настроены.
Я предполагаю, что TCP BTL сбивается с толку виртуальными интерфейсами (vmnet?) При работе на нескольких узлах. Я ограничил используемые интерфейсы с помощью аргумента «—mca btl_tcp_if_include eth0». и это решило мою проблему.