簡體   English   中英

如何在QT中使用MPI?

[英]How to use MPI with QT?

我試圖創建一個圖像處理程序,其中我只有一個帶有按鈕的窗口,而沒有。 我需要在諸如傅立葉變換和高/低通等繁重的處理功能上使用MPI。

我的問題是此窗口是使用QT制作的,而我無法創建一個可以調用其他任務來執行那些繁重的處理功能的窗口。 我怎樣才能做到這一點?

因此,為了清楚起見,我想要的是:

A-我的程序初始化一次。

B-用戶加載圖像並單擊“傅立葉”按鈕后,將開始進行傅立葉計算。

C-在傅立葉計算的中間,我必須與MPI進行並行化,在該過程中,我將部分零件發送到其他進程,然后在完成傅立葉處理后將其全部收集。

這可能嗎? 到目前為止,我所掌握的是代碼的串行部分,並開始使用MPI。 在第一個glympse中,我有多個運行多個窗口的進程(例如同時打開5個mspaints)。 為了解決這個問題,我嘗試了以下方法:

if ( pid == 0 )
{   
        QApplication a(argc, argv);

    MainWindow w;
        w.show();

    a.exec();
}

這將創建一個窗口。 我試圖通過這樣做來並行化for循環:

    if ( pid == 0 )
    {
        printf("This is the master task. There are %d tasks in total", nProcs);

        for ( i = 1; i < nProcs; i++ )
        {
            MPI_Send( &complexPixel[i*width/nProcs][0], width*height/nProcs,  MPI_DOUBLE, i, tag, MPI_COMM_WORLD );
                MPI_Send( &H,   width*height, MPI_DOUBLE, i, tag, MPI_COMM_WORLD );
        }
    }
    else
    {
            printf("This is a slave task. PID = %d\n", pid);
            MPI_Recv( &complexPixel, width*height/nProcs, MPI_DOUBLE, 0, tag, MPI_COMM_WORLD, &statusMPI );
            MPI_Recv( &H, width*height,  MPI_DOUBLE, 0, tag, MPI_COMM_WORLD, &statusMPI );
        }
    }

    DoSomeWork();

    if ( pid != 0 )
    {
        MPI_Send( &T, width*height/nProcs, MPI_DOUBLE, 0, tag, MPI_COMM_WORLD );
        printf("Slave work finished.\n");
    }
    else
    {
        for ( i = 1; i < nProcs; i++ )
                MPI_Recv( &T[i*width/nProcs][0], width*height/nProcs, MPI_DOUBLE, i, tag, MPI_COMM_WORLD, &statusMPI );
            printf("Master work finished.\n");
    }

現在,我陷入了第一個MPI_Send,因為自從我命令主任務執行整個窗口以來,這似乎是唯一能夠處理它的進程。

感謝您的時間! 希望我能使它工作!

我很樂意對Qt和MPI使用單個過程:使用線程將用戶界面行為與MPI和計算分開-這樣您就擁有了響應式用戶界面。 雖然並非沒有挑戰。

哪個線程做什么?

  • 有一個有據可查的文檔,所有GUI工作都必須位於“主線程”中-這實際上對於Linux並不是必需的,但對於OS / X (以前的S / O回答)卻是必需的。
  • 這與MPI沖突-MPI中許多MPI不支持或需要專門編譯才能啟用多個線程。 閱讀MPI_Init_thread的手冊頁,因為這可以幫助您確定線程支持的級別。

碰巧的是,最常見的MPI(開放MPI)在MPI_THREAD_FUNNELED和MPI_THREAD_SINGLE (先前的討論)之間沒有區別-這意味着只要您僅將非GUI線程用於MPI,您就可以了。

圖書館

如果對應用程序中的每個進程都使用相同的二進制文件,則必須確保在計划使用群集的群集的節點上庫依賴項可用,而不僅僅是使用群集(登錄節點)。 GUI正在運行。 在實踐中,這可能很痛苦:除非您僅使用QtCore並擁有非GUI應用程序,否則Qt會帶來很多X依賴項。

開放式MPI(以及許多其他MPI)使您可以使用多個不同的二進制文件-因此,您可以為一個進程(在GUI節點上)運行與GUI鏈接的代碼的一個版本,而其他版本可以是單線程非GUI QtCore鏈接的應用程序,並且具有較少的庫依賴性。

我認為您絕對應該嘗試將顯示GUI的二進制文件與進行計算的二進制文件完全分開。 我會嘗試以下。

創建一個實現GUI的程序。 該程序必須分配共享內存(或在shm分區中創建文件)。 創建第二個程序,用MPI實現計算; 該程序的主進程必須與GUI程序在同一節點上運行,並訪問相同的共享內存(或文件)。 其他進程一直等到它們從主進程獲得集體通信(例如MPI_BcastMPI_Gather )。

主進程依次等待,直到GUI程序觸發信號為止,該信號在收集到用戶輸入並填充了共享緩沖區(或文件)后立即發出。 此時,主進程發出集體通信,並且開始通過MPI進行計算。

計算結束后,主進程會立即收集輸出,使用共享內存(或文件)將其返回給GUI程序,或將其寫入輸出文件,或者您必須執行的任何操作,然后告訴GUI程序如果GUI程序正在輪詢(通過Qt易於實現),則通過另一個信號來完成計算,或者仍然使用共享內存。

最后,請記住,使用MPI不能像使用OpenMP那樣“並行化循環”:您必須設計整個過程以及這些過程之間的通信。 並且避免混合用戶界面(無論是Qt,curses,CLI等),並且計算允許將兩個截然不同的任務交給程序員,並使用不同的編譯器標志進行編譯(例如,您可能希望對計算量進行編譯帶有-O3的部件和帶有-O2或-Os的GUI的部件)。

暫無
暫無

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

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