簡體   English   中英

MPI中點對點通信引起的死鎖,使用循環從master發送到children

[英]Deadlock caused by point-to-point communication in MPI, using a loop to send from master to children

我正在嘗試解決作業問題以調試以下單元測試。

基本上,主進程生成隨機整數並將它們發送到子進程以檢查素數,結果被傳送回主進程,算法結束。

我知道應該用集體交流來代替循環,但這是問題的不同部分。 我想了解為什么我這里的這段代碼會導致死鎖。

通過閱讀其他問題,我知道發送/接收的數量應該相互匹配。 但是,我不明白在我的代碼中情況並非如此。

當前的行為是找到一個質數,將其發送回主進程,此時程序會掛起 - 直到使用 ctrl-C 手動取消它。

我知道這不是解決這個問題的慣用方法,但真的很想知道這種方法中的錯誤在哪里。

謝謝!


TEST_CASE("3a - Finding prime numbers", "[MPI]" )
{
    int rank, size;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    // Random number generation
    std::minstd_rand generator;
    unsigned min(2342), max(12342340);
    std::uniform_int_distribution<> distribution(min, max);

    // candidates too big, one of the size values is the master node
    std::vector<unsigned> candidates(size - 1);

    // Main loop continues until a prime is found
    int found_prime(0);
    while (found_prime == 0) {


        if (rank == 0) {

            // Create some candidate numbers for each process to test
            std::generate(candidates.begin(), candidates.end(),
                          [&]() { return distribution(generator); });

            // Send one to each worker
            for (int worker(1); worker < size; ++worker) {
                int rc = MPI_Ssend(&candidates[worker - 1], 1, MPI_UNSIGNED,
                                   worker, 0, MPI_COMM_WORLD);
                REQUIRE(rc == MPI_SUCCESS);
            }

            // Receive whether it was prime
            for (int worker(1); worker < size; ++worker) {
                unsigned result;
                int rc = MPI_Recv(&result, 1, MPI_UNSIGNED, worker, 0,
                                  MPI_COMM_WORLD, MPI_STATUS_IGNORE);
                REQUIRE(rc == MPI_SUCCESS);
                if (result == 1) {
                    found_prime = candidates[worker - 1];
                    std::cout << "Worker " << worker << " found prime "
                              << found_prime << std::endl;
                }
            }
        } else {
            // Receive the candidate to check
            unsigned candidate;
            int rc = MPI_Recv(&candidate, 1, MPI_UNSIGNED, 0, 0, MPI_COMM_WORLD,
                              MPI_STATUS_IGNORE);
            REQUIRE(rc == MPI_SUCCESS);
            // Do the check
            unsigned is_prime = mp::IsPrime(candidate) ? 1 : 0;
            // Return the result
            rc = MPI_Ssend(&is_prime, 1, MPI_UNSIGNED, 0, 0, MPI_COMM_WORLD);
            REQUIRE(rc == MPI_SUCCESS);
        }
    }
    std::cout << "Finished" << rank << std::endl;
}

我對 MPI 一無所知,但是在您的代碼中,如果rank != 0 ,則永遠無法退出 while 循環,因為found_prime從未在else分支中設置(並且rank也從未更改)。

編輯:

正如@DanielLangr 所說,奴隸將需要一種方法來發現沒有更多的工作要來和退出(循環)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM