amirre
amirre

Reputation: 31

using mpirun -np in python script

I want to run a pw.x in bash with this command: mpirun -np 4 pw.x < input.in through a python script. I used this:

from subprocess import Popen, PIPE

process = Popen( "mpirun -np 4 pw.x", shell=False, universal_newlines=True,
                  stdin=PIPE, stdout=PIPE, stderr=PIPE )
output, error = process.communicate();
print (output);

but it gives me this error:

Original exception was:
Traceback (most recent call last):
  File "test.py", line 6, in <module>
    stdin=PIPE, stdout=PIPE, stderr=PIPE )
  File "/usr/lib/python3.6/subprocess.py", line 709, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.6/subprocess.py", line 1344, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'mpirun -np 4 pw.x': 'mpirun -np 4 pw.x'

How can I use "mpirun -np ..." in python scripts?

Upvotes: 0

Views: 2969

Answers (3)

tripleee
tripleee

Reputation: 189830

With shell=False, you need to parse the command line into a list yourself.

Also, unless subprocess.run() is unsuitable for your needs, you should probably avoid calling subprocess.Popen() directly.

inp = open('input.in')
process = subprocess.run(['mpirun', '-np', '4', 'pw.x'],
    # Notice also the stdin= argument
    stdin=inp, stdout=PIPE, stderr=PIPE,
    shell=False, universal_newlines=True)
inp.close()
print(process.stdout)

If you are stuck on an older Python version, maybe try subprocess.check_output()

Upvotes: 0

heemayl
heemayl

Reputation: 42117

When you have shell=False in the Popen constructor, it expects the cmd to be a sequence; any type of str could be one but then the string is treated as the single element of the sequence -- this is happening in your case and the whole mpirun -np 4 pw.x string is being treated as the executable filename.

To solve this, you can:

  • Use shell=True and keep everything else as-is, but beware of the security issues as this would be run directly in shell and you should not do this for any untrusted executable

  • Use a proper sequence e.g. list for cmd in Popen:

    import shlex
    process = Popen(shlex.split("mpirun -np 4 pw.x"), shell=False, ...)
    

Both assuming mpirun exists in your PATH.

Upvotes: 1

johnII
johnII

Reputation: 1433

How about changing

shell=False

to

shell=True

Upvotes: 0

Related Questions