Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to clearly kill a mpi program which is launched by Qprocess?
QtWS25 Last Chance

How to clearly kill a mpi program which is launched by Qprocess?

Scheduled Pinned Locked Moved Unsolved General and Desktop
pyqt5qt5.7mpiqprocess
3 Posts 2 Posters 890 Views
  • 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.
  • S Offline
    S Offline
    SJ2050
    wrote on 26 Feb 2023, 09:17 last edited by
    #1

    I have a pyqt program and there is a requirement to run an external mpi program. I use Qprocess to launch the mpi program. Howerer, I find when I call kill method to terminate the mpi programs, the mpi processes is still running. Do anyone know how to clearly kill the mpi grograms launched by Qprocess?

    Below is my test program:

    test.py

    import sys
    from PyQt5 import QtCore, QtWidgets
    from PyQt5.QtCore import pyqtSignal, QThread, QProcess
    from PyQt5.QtWidgets import QApplication, QWidget
    from PyQt5.QtGui import QTextCursor
    
    class worker(QThread):
        logChange = pyqtSignal(str)
    
        def __init__(self):
            super().__init__()
    
        def run(self):
            process = QProcess()
            command = f"mpiexec -n 8 test_mpi.exe"
            process.start(command)
            process.waitForStarted()
            self.stopFlag = False
            while True:
                if self.stopFlag:
                    process.kill()
                    process.waitForFinished(-1)
                    self.logChange.emit("STOP!\n")
                    break
    
                if process.waitForReadyRead(1000):
                    output = process.readAllStandardOutput()
                    output = bytearray(output).decode("gbk")
                    self.logChange.emit(output)
                else:
                    QApplication.processEvents()
                    if process.state() == 0:
                        self.logChange.emit("FINISHED!\n")
                        break
    
        def stop(self):
            self.stopFlag = True
    
    class Ui_Form(object):
        def setupUi(self, Form):
            Form.setObjectName("Form")
            Form.resize(400, 300)
            self.verticalLayout = QtWidgets.QVBoxLayout(Form)
            self.verticalLayout.setObjectName("verticalLayout")
            self.runButton = QtWidgets.QPushButton(Form)
            self.runButton.setObjectName("runButton")
            self.verticalLayout.addWidget(self.runButton)
            self.stopButton = QtWidgets.QPushButton(Form)
            self.stopButton.setObjectName("stopButton")
            self.verticalLayout.addWidget(self.stopButton)
            self.log = QtWidgets.QTextBrowser(Form)
            self.log.setObjectName("log")
            self.verticalLayout.addWidget(self.log)
            self.retranslateUi(Form)
            QtCore.QMetaObject.connectSlotsByName(Form)
    
        def retranslateUi(self, Form):
            _translate = QtCore.QCoreApplication.translate
            Form.setWindowTitle(_translate("Form", "Form"))
            self.runButton.setText(_translate("Form", "run"))
            self.stopButton.setText(_translate("Form", "stop"))
    
    class MyWidget(QWidget):
        def __init__(self, parent=None):
            super().__init__(parent)
            self.ui = Ui_Form()
            self.ui.setupUi(self)
    
        def logOutput(self, text):
            self.ui.log.insertPlainText(text)
            self.ui.log.moveCursor(QTextCursor.End)
    
        @QtCore.pyqtSlot()
        def on_runButton_clicked(self):
            self.logOutput("start running...\n")
            self.worker = worker()
            self.worker.logChange.connect(self.logOutput)
            self.worker.start()
    
        @QtCore.pyqtSlot()
        def on_stopButton_clicked(self):
            if self.worker:
                self.worker.stop()
                self.logOutput("stop running...\n")
                self.worker = None
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        widget = MyWidget()
        widget.show()
        sys.exit(app.exec_())
    

    test_mpi.cc

    #include "mpi.h"
    #include <iostream>
    #include <chrono>
    #include <thread>
    
    int main(int argc, char** argv) {
      using namespace std::chrono_literals;
      MPI_Init(NULL, NULL);
    
      int world_size;
      MPI_Comm_size(MPI_COMM_WORLD, &world_size);
    
      int world_rank;
      MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
    
      if (world_rank == 0) {
        for (int i = 0; i < 20; i++) {
          std::this_thread::sleep_for(1000ms);
          std::cout << "This output is from test mpi program: " << i << std::endl;
        }
    
        std::cout << "Finished!" << std::endl;
      }
    
      MPI_Finalize();
      return 0;
    }
    

    Snipaste_2023-02-26_16-22-04.png

    And I have learned I can kill it by using taskkill /IM test_mpi.exe /F, but this command will also terminate the test_mpi.exe started by other programs. So my question is how to clearly kill a mpi program which is launched by Qprocess.

    J 1 Reply Last reply 26 Feb 2023, 09:27
    0
    • S SJ2050
      26 Feb 2023, 09:17

      I have a pyqt program and there is a requirement to run an external mpi program. I use Qprocess to launch the mpi program. Howerer, I find when I call kill method to terminate the mpi programs, the mpi processes is still running. Do anyone know how to clearly kill the mpi grograms launched by Qprocess?

      Below is my test program:

      test.py

      import sys
      from PyQt5 import QtCore, QtWidgets
      from PyQt5.QtCore import pyqtSignal, QThread, QProcess
      from PyQt5.QtWidgets import QApplication, QWidget
      from PyQt5.QtGui import QTextCursor
      
      class worker(QThread):
          logChange = pyqtSignal(str)
      
          def __init__(self):
              super().__init__()
      
          def run(self):
              process = QProcess()
              command = f"mpiexec -n 8 test_mpi.exe"
              process.start(command)
              process.waitForStarted()
              self.stopFlag = False
              while True:
                  if self.stopFlag:
                      process.kill()
                      process.waitForFinished(-1)
                      self.logChange.emit("STOP!\n")
                      break
      
                  if process.waitForReadyRead(1000):
                      output = process.readAllStandardOutput()
                      output = bytearray(output).decode("gbk")
                      self.logChange.emit(output)
                  else:
                      QApplication.processEvents()
                      if process.state() == 0:
                          self.logChange.emit("FINISHED!\n")
                          break
      
          def stop(self):
              self.stopFlag = True
      
      class Ui_Form(object):
          def setupUi(self, Form):
              Form.setObjectName("Form")
              Form.resize(400, 300)
              self.verticalLayout = QtWidgets.QVBoxLayout(Form)
              self.verticalLayout.setObjectName("verticalLayout")
              self.runButton = QtWidgets.QPushButton(Form)
              self.runButton.setObjectName("runButton")
              self.verticalLayout.addWidget(self.runButton)
              self.stopButton = QtWidgets.QPushButton(Form)
              self.stopButton.setObjectName("stopButton")
              self.verticalLayout.addWidget(self.stopButton)
              self.log = QtWidgets.QTextBrowser(Form)
              self.log.setObjectName("log")
              self.verticalLayout.addWidget(self.log)
              self.retranslateUi(Form)
              QtCore.QMetaObject.connectSlotsByName(Form)
      
          def retranslateUi(self, Form):
              _translate = QtCore.QCoreApplication.translate
              Form.setWindowTitle(_translate("Form", "Form"))
              self.runButton.setText(_translate("Form", "run"))
              self.stopButton.setText(_translate("Form", "stop"))
      
      class MyWidget(QWidget):
          def __init__(self, parent=None):
              super().__init__(parent)
              self.ui = Ui_Form()
              self.ui.setupUi(self)
      
          def logOutput(self, text):
              self.ui.log.insertPlainText(text)
              self.ui.log.moveCursor(QTextCursor.End)
      
          @QtCore.pyqtSlot()
          def on_runButton_clicked(self):
              self.logOutput("start running...\n")
              self.worker = worker()
              self.worker.logChange.connect(self.logOutput)
              self.worker.start()
      
          @QtCore.pyqtSlot()
          def on_stopButton_clicked(self):
              if self.worker:
                  self.worker.stop()
                  self.logOutput("stop running...\n")
                  self.worker = None
      
      if __name__ == "__main__":
          app = QApplication(sys.argv)
          widget = MyWidget()
          widget.show()
          sys.exit(app.exec_())
      

      test_mpi.cc

      #include "mpi.h"
      #include <iostream>
      #include <chrono>
      #include <thread>
      
      int main(int argc, char** argv) {
        using namespace std::chrono_literals;
        MPI_Init(NULL, NULL);
      
        int world_size;
        MPI_Comm_size(MPI_COMM_WORLD, &world_size);
      
        int world_rank;
        MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
      
        if (world_rank == 0) {
          for (int i = 0; i < 20; i++) {
            std::this_thread::sleep_for(1000ms);
            std::cout << "This output is from test mpi program: " << i << std::endl;
          }
      
          std::cout << "Finished!" << std::endl;
        }
      
        MPI_Finalize();
        return 0;
      }
      

      Snipaste_2023-02-26_16-22-04.png

      And I have learned I can kill it by using taskkill /IM test_mpi.exe /F, but this command will also terminate the test_mpi.exe started by other programs. So my question is how to clearly kill a mpi program which is launched by Qprocess.

      J Offline
      J Offline
      JonB
      wrote on 26 Feb 2023, 09:27 last edited by
      #2

      @SJ2050
      Your QProcess::start() only launches mpiexec, not test_mpi.exes. You cannot access the PIDs of the test_mpi.exes that spawns. At best you might be able to find those test_mpi.exes still running whose parent PID is the PID of the original mpiexec launched.

      Forget QProcess. Tell us how from the command line you would kill exactly those spawned from the desired mpiexec and yet no others which might have been started elsewhere?

      S 1 Reply Last reply 26 Feb 2023, 12:34
      0
      • J JonB
        26 Feb 2023, 09:27

        @SJ2050
        Your QProcess::start() only launches mpiexec, not test_mpi.exes. You cannot access the PIDs of the test_mpi.exes that spawns. At best you might be able to find those test_mpi.exes still running whose parent PID is the PID of the original mpiexec launched.

        Forget QProcess. Tell us how from the command line you would kill exactly those spawned from the desired mpiexec and yet no others which might have been started elsewhere?

        S Offline
        S Offline
        SJ2050
        wrote on 26 Feb 2023, 12:34 last edited by
        #3

        @JonB In command line, we usually kill a mpi program by killing one of the child processes. And I find this may be a bug of intel mpi on windows [ https://community.intel.com/t5/Intel-oneAPI-HPC-Toolkit/InteloneAPI-MPI-2021-2-0-behavior-on-Linux-and-Windows-differ/td-p/1290020 ]. Anyway, thanks for your reply.

        1 Reply Last reply
        1

        3/3

        26 Feb 2023, 12:34

        • Login

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