gettimeofday вылетает MPI?
У меня есть MPI-программа, время выполнения которой я пытаюсь измерить. Поэтому я добавляю 2 звонка к gettimeofday, и там все перестает работать. По какой-то причине, это происходит сбой, только если у меня есть второй вызов gettimeofday там. Вот сообщение, которое я получаю:
Приложение MPI ранга 0 убито перед MPI_Finalize() с сигналом 11 srun: ошибка: n32: task0: выход с кодом выхода 245
Вот код
struct timeval starttime;
struct timeval endtime;
gettimeofday(&starttime, NULL);
int numDarts = 1000000000;
int numWorkers = 2;
char* args[1];
if(argc >= 2)
{
numWorkers = atoi(argv[1]);
}
if(argc >= 3)
numDarts = atoi(argv[2]);
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
printf("world size = %i\n", world_size);
if (world_size != 1)
printf("Top heavy with management\n");
int numDartsWorker = numDarts/numWorkers;
int numDartsMaster = numDarts/numWorkers + (numDarts % numWorkers); //the master computes the leftover
args[0] = malloc(256 * sizeof(char));
sprintf(args[0], "%i", numDartsWorker);
// printf("argument passing to workers: %s\n", args[0]);
/*
* Now spawn the workers. Note that there is a run-time determination
* of what type of worker to spawn, and presumably this calculation must
* be done at run time and cannot be calculated before starting
* the program. If everything is known when the application is
* first started, it is generally better to start them all at once
* in a single MPI_COMM_WORLD.
*/
// printf("About to call MPI_Comm_spawn with %i workers...\n", numWorkers);
int resultLen = 0;
//the master counts as a worker, hence the -1
MPI_Comm_spawn("piworker", args, numWorkers-1, MPI_INFO_NULL, 0, MPI_COMM_SELF,
&everyone, MPI_ERRCODES_IGNORE);
double pisum = 0;
double myresult = dboard(numDartsMaster);
printf("parent result is %.9f\n", myresult);
int rc = MPI_Reduce(&myresult, &pisum, 1, MPI_DOUBLE, MPI_SUM, MPI_ROOT, everyone);
if (rc != MPI_SUCCESS)
printf("failure on mpi_reduce\n");
free(args[0]);
/*
* Parallel code here. The communicator "everyone" can be used
* to communicate with the spawned processes, which have ranks 0,..
* MPI_UNIVERSE_SIZE-1 in the remote group of the intercommunicator
* "everyone".
*/
//receive the results
int i=1;
MPI_Status status;
double avgpi = pisum;
avgpi += myresult; //include master's average in the result.
avgpi /= numWorkers;
printf("startTime = %d secs, %d microsecs\n", starttime.tv_sec);
// gettimeofday(&endtime, NULL);
// double totalTime = ((double)endtime.tv_sec + (double)endtime.tv_usec/1000000.0f) -
// ((double)starttime.tv_usec + (double)starttime.tv_usec/1000000.0f);
// printf("Total time: %.8f\n", totalTime);
printf("With %i workers, %i darts, estimated value of pi is: %.9f\n", numWorkers, numDarts, avgpi);
MPI_Finalize();
return 0;
}
Я вставил вызов printf как раз перед вторым вызовом gettimeofday. Он только распечатывает что-либо, если второй вызов закомментирован, в противном случае происходит сбой. Я прокомментировал gettimeofday в этом примере, но это вызов, который вызывает сбой mpi. Если я откомментирую это, оно снова начнет падать с сообщением об ошибке, которое я упомянул.
Мне интересно, есть ли у кого-нибудь понимание того, почему gettimeofday будет делать это.
2 ответа
В вашем коде есть порождение потоков, как в
//the master counts as a worker, hence the -1
MPI_Comm_spawn("piworker", args, numWorkers-1, MPI_INFO_NULL, 0, MPI_COMM_SELF,
&everyone, MPI_ERRCODES_IGNORE);
и впоследствии арг освобождается как в
free(args[0]);
Это ожидается? Не повлияет ли свободный объем памяти на отдельные потоки?
Благодаря nos, которые прокомментировали мой вопрос, я смог найти решение. Я избавился от вызова sprintf, который использовался для записи в строку аргумента вызова MPI_Comm_Spawn, который говорил рабочим, сколько "дротиков" использовать. Вместо этого я использую MPI_Send для отправки им информации. Похоже, что sprintf не был проблемой, пока я не позвонил gettimeofday.