c++ - 如何将 MPI 与 QT 一起使用?

标签 c++ qt parallel-processing mpi

我正在尝试创建一个图像处理程序,其中我只有一个带按钮的窗口,什么都没有。我需要在繁重的处理函数上使用 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 是 (previous S/O answer) .
  • 这与 MPI 冲突 - 许多 MPI 要么不支持,要么需要专门编译以启用多线程。阅读 MPI_Init_thread 的手册页,因为这可以帮助您确定线程支持级别。

碰巧,最常见的 MPI,Open MPI,在 MPI_THREAD_FUNNELED 和 MPI_THREAD_SINGLE 之间没有区别 (previous discussion) - 这意味着只要您只对 MPI 使用非 GUI 线程,就可以了。

如果您对应用程序中的每个进程使用相同的二进制文件,那么如果您计划使用集群,则必须确保库依赖项在集群的节点上可用 - 而不仅仅是节点(登录节点) ) 运行 GUI 的位置。在实践中,这可能会很痛苦:除非您只使用 QtCore 并且有一个非 GUI 应用程序,否则 Qt 会引入很多 X 依赖项。

Open MPI(以及许多其他 MPI)允许您使用多个不同的二进制文件 - 因此您可以为一个进程(在 GUI 节点上)运行一个与 GUI 事物链接的代码版本,而其他进程可以是单线程非 - GUI QtCore 链接应用程序并且具有更少的库依赖性。

关于c++ - 如何将 MPI 与 QT 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17099501/

相关文章:

c++ - botan加密如何检查输入的密码是否正确

qt - 如何更改 QTableView 的标题标题?

matlab - 全局变量和 parfor

c# - 在我的 asp.net mvc web 应用程序中使用 Parallel.Foreach 和 WebClient() 有什么缺点或风险吗

c++ - SFINAE 确定类型是否有方法

c++ - 变量初始化和构造函数

c++ - 使用 map 将字符串与枚举连接起来

qt - 除了 GUI 相关类之外,Qt 是否还有通用类?

c - 前缀和的并行化 (Openmp)

c++ - 关闭多线程 NSDocument