Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. General talk
  3. Brainstorm
  4. Qt OpenMPI wrap
Forum Updated to NodeBB v4.3 + New Features

Qt OpenMPI wrap

Scheduled Pinned Locked Moved Brainstorm
8 Posts 2 Posters 4.2k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • kshegunovK Offline
    kshegunovK Offline
    kshegunov
    Moderators
    wrote on last edited by
    #1

    Hello,
    Sometime in the following 6 months to a year I would have to put up a computationally-intensive application and I'm thinking of doing a somewhat simple wrap around the OpenMPI library. The best case scenario would be to have that Qt signal-slot sweetness available out of the box for each computational node. I know that interest in such a thing will probably be on the low-side, but was wondering how I could go around designing it. Suppose I put my code in a dynamic library where I derive from QCoreApplication and do the OpenMPI init/deinit there. What I'm not quite sure how to do is actually designing a nicely flowing transition from the OpenMPI messages to the Qt's signal-slot mechanism. Does someone have an idea, a suggestion?

    Kind regards.

    Read and abide by the Qt Code of Conduct

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Just to be sure I understand you correctly, do you want to use Qt to write MPI jobs ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      kshegunovK 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        Just to be sure I understand you correctly, do you want to use Qt to write MPI jobs ?

        kshegunovK Offline
        kshegunovK Offline
        kshegunov
        Moderators
        wrote on last edited by kshegunov
        #3

        @SGaist
        Yep! I know it to be possible since I've already done it for another project, however I used the "OpenMPI" way for the message handling (receiving, sending) only I had an intermediary that serialized/deserialized my Qt objects to byte arrays, so I could move them around the nodes.

        EDIT:
        What do you mean by jobs? If you meant the job managment for the cluster, no there's a queue manager for that. I mean to write an application that utilizes the OpenMPI library and Qt. An OpenMPI node forks the main() of the program but nodes communicate between themselves via messages. You could think it as a inter-process communication, which I'd like to make a bit easier for me (and possibly others) by wrapping the message passing between the nodes as signal-slot connections.

        Read and abide by the Qt Code of Conduct

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          So a Qt version of mpirun ?

          Nice new avatar, reminds me of the old forum highest rank badge :)

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          kshegunovK 1 Reply Last reply
          0
          • SGaistS SGaist

            So a Qt version of mpirun ?

            Nice new avatar, reminds me of the old forum highest rank badge :)

            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by kshegunov
            #5

            @SGaist

            Nice new avatar, reminds me of the old forum highest rank badge

            Thanks. Although I don't know the badge itself, it's strange it would resemble an atom ... :)

            So a Qt version of mpirun ?

            Well ... no. mpirun is just fine. I shall provide some example code (from an old project), and maybe it'll become clear what I'd like to do exactly. When one makes a program that runs on a cluster (or a PC using OpenMPI) one ordinarily has something like this (this is extracted from a class, so don't take note of the undefined/unused variables):

            int main(int argc, char ** argv)
            {
            	MPI_Init(&argc, &argv);
            
            	// Waiting variables
            	QMutex waitMutex;
            	QMutexLocker dummyLock(&waitMutex);
            	QWaitCondition waitCondition;
            
            	// Process messages
            	MPI_Status status;
            	while (hasMessageLoop)  {
            		if (MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &messageAvailable, &status) != MPI_SUCCESS)  {
            			cerr << QStringLiteral("Error probing for MPI message, process exiting!") << endl;
            			break;
            		}
            
            		if (!messageAvailable)  {
            			// No message, sleep 1 second and try again.
            			// NOTE: Since each task is quite slow to process there is no real reason for the busy wait implemented by MPI_Probe! Instad just poll for messages each second.
            			waitCondition.wait(&waitMutex, 1000);
            			continue;
            		}
            
            		try  {
            			processMessage(status);
            		}
            		catch (QString message)
            		{
            			cerr << message << endl;
            			break;
            		}
            	}
            
            	MPI_Finalize();
            
            	return 0;
            }
            

            As you can see this is just an ordinary event loop. Similarly on how events are generated for Qt by the window system, here they are in fact "generated" by OpenMPI. They are not what you'd call spontaneous in Qt's terms, however the principle of handling them is pretty much the same. Now suppose there's a way that each node will know about each other node (they have int identifiers, so they can be distinguished) and at some point while processing data you want to send a message to another node. you'd issue something like:

            MPI_Send(&pointIndex, sizeof(pointIndex), MPI_INT32_T, status.MPI_SOURCE, MSG_TAG_PROCESS_POINT, MPI_COMM_WORLD);
            

            However probing (as in the event loop above is simply not enough, to get that last message you've sent, you'd want to call a corresponding receive, like this:

            	int size;
            	if (MPI_Get_count(&status, MPI_CHAR, &size) != MPI_SUCCESS || size == MPI_UNDEFINED)
            		throw QStringLiteral("Can't get size for data");
            
            	// Receive the initial data
            	char * data = new char[size];
            	MPI_Recv(data, size, MPI_CHAR, status.MPI_SOURCE, status.MPI_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
            

            And so you have communication between the nodes. This is obviously a bit cumbersome, and I believe could greatly be improved upon, by using Qt and it's signal slot mechanism. I envision a "syntax" like this:

            class MyMpiController : public QObject
            {
            	// ...
            };
            
            int main(int argc, char ** argv)
            {
            	QMpiApplicaton application(argc, argv);
            	MyMpiController controller;
            
            	QObject::connect(&application, &QMpiApplication::initialize, [&controller] ()  {
            		QObject::connect(QMpiNode::currentNode(), SIGNAL(messageReceived(QMpiMessage), &controller, SLOT(processMessage));
            	});
            
            	return QMpiApplicaton::exec();
            }
            

            Obviously, such a way could use a lot of improvement, but let's say that it's a starting point. Now, for this to be feasible I'd have to hack up Qt's event loop, and replace it with my own - this I'm still not quite clear how to do. I should also transmit some messages between the nodes for internal purposes (like reporting which node is online, and requesting them to quit). This I believe would be pretty straight-forward. The thing is that it'd be best if I could somehow connect a messageReceived slot for each of the message types, which I'm also not very clear how I could do. The MPI send/receive specifics wouldn't be a problem since everything can be serialized before sending and deserialized before receiving.
            I hope that cleared it up.

            Kind regards.

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Way clearer, thanks for the detailed explanation.

              Do you plan to support both sync and async message passing ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              kshegunovK 1 Reply Last reply
              0
              • SGaistS SGaist

                Way clearer, thanks for the detailed explanation.

                Do you plan to support both sync and async message passing ?

                kshegunovK Offline
                kshegunovK Offline
                kshegunov
                Moderators
                wrote on last edited by kshegunov
                #7

                @SGaist
                Indeed, I do. It's pretty simple to add a blocking/nonblocking flag for the message. I'm advancing with the event dispatcher as well. I'm now pulling the messages from MPI and soon I'll be implementing the application-level event processing. I'll be using the metatype ID for the message classes as the "message tag" (what OMPI guys call the message type) and will be using the meta system heavily to create objects based on that on reception of the messages.

                The only problem I see is that MPI_Probe (blocking check for a pending message) does not support timeouts and I can't select on a file to get real async behavior. However, MPI_Probe implements busy wait itself so I'll be just running the event loop without blocking and with the non-blocking probing, so everything should be fine.

                Kind regards.

                Read and abide by the Qt Code of Conduct

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Sounds good !

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved