如何在python/numpy中自动化BLAS的环境变量相关基准测试



我需要一些帮助来弄清楚如何在python中自动化基准测试工作。

我正在通过python中的numpy测试线程对BLAS库调用的影响。在linux环境中,OpenBLAS中的线程通过环境变量OMP_NUM_THREADS进行控制。我想做一个测试,将OMP_NUM_THREADS从1增加到一个最大值,在每个线程计数时为例程计时,然后最终操作所有线程计数的聚合计时。

问题如下。环境变量可以在python中设置,但它们只影响子流程或子shell。因此,我可以使用以下驱动程序代码正确运行我的基准测试:

#!/usr/bin/env python                                                                                                     # driver script for thread test
import os
thread_set =[1,2,4,8,16]
for thread in thread_set:
os.environ['OMP_NUM_THREADS']='{:d}'.format(thread)
os.system("echo $OMP_NUM_THREADS")
os.system("numpy_test")

和numpy_test脚本:

#!/usr/bin/env python
#timing test for numpy dot product (using OpenBLAS)                                                      
#based on http://stackoverflow.com/questions/11443302/compiling-numpy-with-openblas-integration
import sys
import timeit
setup = "import numpy; x = numpy.random.random((1000,1000))"
count = 5
t = timeit.Timer("numpy.dot(x, x.T)", setup=setup)
dot_time = t.timeit(count)/count
print("dot: {:7.3g} sec".format(dot_time))

但分析这是一个非常手工的过程。

特别是,我不能将值dot_timenumpy_test返回到我的外部包装程序,所以我不能以任何自动化的方式分析我的测试结果。例如,我想绘制dot_time与线程数的关系图,或者评估dot_time/线程数是否恒定。

如果我试图通过定义一个python测试函数(避免上面的os.system()方法),然后在thread in thread_set循环中运行测试函数,在python实例中完全执行类似的测试,那么测试函数的所有实例都继承了OMP_NUM_THREADS的相同值(父python shell的值)。所以这个测试失败了:

#!/usr/bin/env python
#attempt at testing threads that doesn't work
#(always uses inherited value of OMP_NUM_THREADS)
import os
import sys
import timeit
def test_numpy():
setup = "import numpy; x = numpy.random.random((1000,1000))"
count = 5
t = timeit.Timer("numpy.dot(x, x.T)", setup=setup)
dot_time = t.timeit(count)/count
print("dot: {:7.3g} sec".format(dot_time))
return dot_time
thread_set =[1,2,4,8,16]
for thread in thread_set:
os.environ['OMP_NUM_THREADS']='{:d}'.format(thread)
os.system("echo $OMP_NUM_THREADS")
time_to_run = test_numpy()
print(time_to_run)

由于test_numpy()总是继承父环境中OMP_NUM_THREADS的值,而不是通过os.environ()设置的值,因此thread的每个实例都占用相同的时间。然而,如果这样的事情奏效了,那么做我需要做的分析将是微不足道的

在真正的测试中,我将运行1000多个排列,所以自动化是关键。考虑到这一点,我很乐意回答以下任何一个问题:

  1. 如何从这样的子流程返回值(dot_time)?有比读/写文件更优雅的解决方案吗?

  2. 有没有更好的方法来构建这种(依赖于环境变量的)测试?

提前谢谢。

您可以这样做:

import subprocess
os.environ['OMP_NUM_THREADS'] = '{:d}'.format(thread)
proc = subprocess.Popen(["numpy_test"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()

然后,您将在stdout中获得numpy_test脚本的输出。总的来说,我认为subprocess.callsubprocess.Popenos.system更受欢迎。

如果您想从子流程获得输出,请使用subprocess.check_output,例如替换

os.system("numpy_test")

带有

dot_output = subprocess.check_output(["numpy_test"])
dot_time = ... # extract time from dot_output

相关内容

  • 没有找到相关文章

最新更新