2017-06-10 15 views
0

ベンチマークドライバプログラムをPythonで作成しています。その目的は、入力としていくつかのC++ソースファイル(。 cpp)を実行し、各入力ファイルをコンパイルし、その実行可能ファイルを作成し(.out)、その実行可能ファイルをコマンドライン引数としてその実行可能ファイルに実行します。実行可能ファイルが実行されている間は、すべて)/usr/bin/timeを使用します。ベンチマーク中にpython3.5でsubprocess.run(....)の出力をファイルに書き出す

だから、他の言葉で、何このドライバプログラムがやっていることは(実行のタイミングを測定するために使用される)この文を自動化しようとしている。このなステートメントで

   /usr/bin/time ./way1.out 10 > way1.output 

way1.out(C++プログラムへの入力実行可能ファイル)が10でC++プログラムの出力がway1.outputに書き込まれた後、時刻情報がコンソールに/usr/bin/timeで出力されます。 Ofcourseは、10の代わりに(このステートメントのように)、1から10^6までのすべての数値に対してこのコマンドを実行するのはドライバプログラムです。ドライバプログラムはすべての入力C++ソースファイルに対してこれを行い、各ソースファイルの出力は/usr/bin/time(各値は1〜10^6)から別のファイルに書き出します(後でそのソースコードのベンチマーク結果を解析します) 。私はのpython3のsubprocessモジュールを使用して、この行のsubprocess.runすなわちrun方法だ使用、そう

#!/usr/bin/env python3.5 

import subprocess 
import sys 

n_limit = 1000000 
files_list = ["./src/way1.cpp", "./src/way2.cpp"] 

def compile_programs(files_list): 
    try: 
     for eachFile in files_list: 
      subprocess.run(["g++", "-std=c++14", eachFile, "-o", eachFile.split(".")[1].split("/")[2] + ".out"], check=True) 
    except: 
     print("Some error occured") 
     return False 

    return True 


def benchmark(files_list): 

    if compile_programs(files_list): 
     print("\n\n Compilation Successful") 
    else: 
     raise Exception("Compilation Problem") 

    print("\n\n Benchmarking started..") 
    for eachFile in files_list: 
     current_file_name = eachFile.split(".")[1].split("/")[2] 

     with open(current_file_name + ".results", 'w') as each_file_bench_results: 
      for n in range(1, n_limit + 1): 

       print(" Currently running for n =", n, " for filename:", eachFile) 

       with open(current_file_name+".output", 'w') as current_output_file: 
        completed_process = subprocess.run(["/usr/bin/time", "./" + current_file_name + ".out", str(n)], stdout=current_output_file) 
        each_file_bench_results.write(completed_process.stdout) 

       subprocess.run(["rm", current_file_name + ".output"]) 
       print() 

    print("\n\n Benchmarking Complete.. Results files are with '.results' extensions") 

if __name__ == "__main__": 
    if (len(sys.argv) == 1): 
     print("Using default ./src/way1.cpp and ./src/way2.cpp") 
     benchmark(files_list) 
    else: 
     benchmark(*sys.argv[1:]) 

completed_process = subprocess.run(["/usr/bin/time", "./" + current_file_name + ".out", str(n)], stdout=current_output_file)

C++プログラム

この

は私driver.pyです入力を受け取り、実行し、その出力をファイルに出力しますが、出力はです210は、端末に印刷されたので、私はこの試みたばかりされています。それは、completed_process.stdoutはなしではありませんので、ファイルに書き込まれないことが判明したが、

each_file_bench_results.write(completed_process.stdout)

しかし、を私はこのコメント場合ステートメントが終了すると、/usr/bin/timeの出力が端末に出力されます。

私の質問は、の出力をeach_file_bench_resultsに書き込む方法です。

答えて

1

はSTDOUTとSTDERRの両方をキャプチャしてみてください。

completed_process = subprocess.run(
    ["/usr/bin/time", "./" + current_file_name + ".out", str(n)], 
    stdout=current_output_file, stderr=each_file_bench_results 
) 

/usr/bin/timeは(少なくとも私のシステム上の)部分的にSTDERRへの書き込みを行うことが表示されます。 subprocess.check_output()を使用して、受信した出力をより詳細に制御できる、より便利なアプローチをとることもできます。

+0

本当にありがとうございましたが、うまくいきましたが、なぜ、/ usr/bin/timeがSTDERRに書き込むのですか? – tkhurana96

+0

私は自分の開発者に尋ねる必要があります。現在のSTDOUTに干渉することなくバックグラウンドで実行できるのでしょうか?いずれにしても、[source](http://code.metager.de/source/xref/OpenBSD/src/usr.bin/time/time.c)を確認すると、部分的ではなく、排他的に書き込みが行われますSTDERRに。 – zwer

+0

ありがとう@ zwen、私は間違いなくそれを開発者に依頼し、そのsouceも見ています。これを回答として受け入れる – tkhurana96

関連する問題