2015-11-03 50 views
2

我有一个python脚本,使用mpi4py调用main_parallel.py。我可以使用time来测量时间cli,但是,我怎样才能制作一个类似于cProfile的配置文件?我希望看到代码每个部分的调用次数。我无法使用cProfile,因为它仅适用于串行代码。配置文件并行python脚本与mpi4py

谢谢!

回答

3

为什么你不能使用cprofile?你有没有尝试过?

对于MPICH,我跑是这样的:

$ mpiexec -l -np 4 python -m cProfile ./simple-io.py doodad 

这给了我4套输出,但“-l”参数列表输出的每一位的前面MPI等级。注意:'-l'参数是MPICH特有的。 OpenMPI使用--tag-output。其他实现可能使用其他的东西。

我看到cprofile可以带一个文件名参数。使每级的输出文件,然后用统计

% python 
Python 2.7.10 (default, Oct 14 2015, 16:09:02) 
[GCC 5.2.1 20151010] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import pstats 
>>> pstats.Stats("simple-io.cprofile").sort_stats('cumulative').print_stats() 

处理它给了我很多的CPROFILE信息......但我的玩具方案过于微小,可以给我任何有用的东西。

+0

我'mpiexec'(1.10.2从Ubuntu 16.04包管理器)可视化似乎没有'-l'开关。没有它,我只能得到一个输出文件,显然是为0级。考虑到我的安装比你的答案更新,也许你的答案已过时? – NichtJens

+0

谢谢。 1.10.2来自OpenMPI。我已经更新了我的答案,以反映前面获得排名的方式是实现特定的并记录两个主要实现。 –

+0

太好了。看起来标准化的“mpiexec”以这种不一致的方式来做这件事有点奇怪。我认为它的目的是为了替换'mpirun',它由于不规范而受到这些不一致性的影响...... – NichtJens

2

由于Rob Latham说你可以使用cProfile。您可以将每个进程的输出保存在不同的文件中。如果要分析的功能,你可以使用这样的装饰:

from mpi4py import MPI 
import cProfile 

def profile(filename=None, comm=MPI.COMM_WORLD): 
    def prof_decorator(f): 
    def wrap_f(*args, **kwargs): 
     pr = cProfile.Profile() 
     pr.enable() 
     result = f(*args, **kwargs) 
     pr.disable() 

     if filename is None: 
     pr.print_stats() 
     else: 
     filename_r = filename + ".{}".format(comm.rank) 
     pr.dump_stats(filename_r) 

     return result 
    return wrap_f 
    return prof_decorator 

@profile(filename="profile_out") 
def my_function(): 
    # do something 

每个过程的输出可以使用snakeviz

+0

是否有在最内层函数中导入cProfile的原因?通过这种方式,它每次都被重新导入... – NichtJens

+0

根据[this](https://stackoverflow.com/a/3095124/6756219),导入缓存且仅导入一次。但是,没有理由将导入保留在最内层功能中,因此您可以将其导入顶层。 – hnfl

+0

是的,你是对的。我忘记了重新导入没有任何处罚。尽管如此,它并不是通常的风格......另外,为MPI单例添加导入行以完成代码可能会很好。编辑:我建议编辑这样做。 – NichtJens