0

我有一个 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;
}

我在第二次调用 gettimeofday 之前打了一个 printf 电话。如果第二个调用被注释掉,它只会打印任何东西,否则它会崩溃。我在此示例中注释掉了 gettimeofday,但这是导致 mpi 崩溃的调用。如果我取消注释它,它会再次开始崩溃,并出现我提到的错误消息。

我想知道是否有人对为什么 gettimeofday 会这样做有任何见解。

4

2 回答 2

1

在您的代码中,有一个线程的产生,如

//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);

随后 args 被释放,如

free(args[0]);

这是预期的吗?释放这些内存不会影响各个线程吗?

于 2013-02-08T23:02:14.913 回答
0

感谢 nos,他对我的问题发表了评论,我能够找到解决方案。我摆脱了对 sprintf 的调用,它被用来写入 MPI_Comm_Spawn 调用的参数字符串,它告诉工作人员要使用多少个“飞镖”。相反,我使用 MPI_Send 向他们发送信息。似乎在我打电话给 gettimeofday 之前,sprintf 不是问题。

于 2013-02-09T01:39:09.327 回答