我正在为一个使用MPI(OpenMPI,如果相关的话)的Fortran库编写Python包装。我在这里提到的问题也恰恰发生在Python包装器到C库的情况下。我必须使用内置的unittest
Python包来测试Python接口
我有下面的MWE,它试图在所有处理器中找到最大和最小整数。以下是Fortran文件:
! File mpitest.F90
module mpitest
implicit none
include "mpif.h"
integer nranks
integer rank
contains
!--------------------------------------------------!
subroutine pympitest_init()
implicit none
integer ierror
call MPI_INIT(ierror)
call MPI_COMM_SIZE(MPI_COMM_WORLD, nranks, ierror)
call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierror)
end subroutine pympitest_init
!--------------------------------------------------!
subroutine get_max_integer(inint, outint)
implicit none
integer, intent(in) :: inint
integer, intent(out) :: outint
integer ierror
call mpi_allreduce(inint,outint,1,mpi_integer,mpi_max,MPI_COMM_WORLD,ierror)
end subroutine get_max_integer
!--------------------------------------------------!
subroutine get_min_integer(inint, outint)
implicit none
integer, intent(in) :: inint
integer, intent(out) :: outint
integer ierror
call mpi_allreduce(inint,outint,1,mpi_integer,mpi_min,MPI_COMM_WORLD,ierror)
end subroutine get_min_integer
!--------------------------------------------------!
subroutine pympitest_final()
integer ierror
call mpi_finalize(ierror)
end subroutine pympitest_final
end module mpitest
下面给出了Python单元测试文件,其中有些内容我已经尝试过,但没有作为注释加入:
#!/usr/bin/env python3
# Python file test_pympitest.py
from __future__ import print_function
import unittest
import numpy as np
from pympitest import mpitest as pm
#--------------------------------------------------------------------#
class Test_Fortran_MPI_functions(unittest.TestCase):
"""Unit test template for testing MPI functions."""
#----------------------------------------------------------------#
#def __init__(self):
# """Try MPI_Initialize -- Does not help."""
# print("Initializing MPI")
# pm.pympitest_init()
#----------------------------------------------------------------#
#def tearDown(self):
# """Try MPI_Finalize -- Does not help."""
# print("Finalizing MPI")
# pm.pympitest_final()
#----------------------------------------------------------------#
def setUp(self):
"""Initialize the unit test."""
print("Initializing MPI")
pm.pympitest_init()
# We'll just test min. and max. of ranks across all PEs.
self.inint = pm.rank
#----------------------------------------------------------------#
def tearDown(self):
"""Finalize the unit test."""
print("Finalizing MPI")
pm.pympitest_final()
#----------------------------------------------------------------#
#----------------------------------------------------------------#
# Two Tests. If you comment out any one of the tests, then the
# unit test runs fine. Keeping both uncommented thorws error
# saying MPI_Init was called after MPI_Final, obviously since
# the setUp and tearDown functions are called every time.
#----------------------------------------------------------------#
def test_get_min_integer(self):
"""Test get_min_integer function."""
minint = pm.get_min_integer(self.inint)
print("Minimum on processor {} = {}".format(pm.rank,minint))
self.assertEqual(minint, 0)
#----------------------------------------------------------------#
def test_get_max_integer(self):
"""Test get_max_integer function."""
maxint = pm.get_max_integer(self.inint)
print("Maximum on processor {} = {}".format(pm.rank,maxint))
self.assertEqual(maxint, pm.nranks-1)
#--------------------------------------------------------------------#
if __name__ == "__main__":
unittest.main()
# Tried the following. Does not help:
# Calls MPI_Initialize but exits without calling MPI_Finalize.
#print("Initializing MPI")
#pm.pympitest_init()
#unittest.main()
#print("Finalizing MPI")
#pm.pympitest_final()
Fortran代码使用f2py
包装到名为pympitest
的Python模块中,如下所示:
f2py --f90exec="mpif90" -DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION -c mpitest.F90 -m pympitest
。单元测试在4个处理器上运行,如:mpirun -np 4 python test_pympitest.py
我希望将所有MPI单元测试保存在一个python文件中。在我尝试过的不同方法中(请参阅Python文件中的注释),我遇到的问题是MPI_Initialize和MPI_Finalize要么在一次运行中多次被调用,要么只调用其中一个,所有这些方法都会以错误退出
如何修复此问题以使单元测试正确通过
Edit(添加):将测试函数放在单个Python文件中单独的Test_...(unittest.TestCase)
类中也没有帮助。将MPI单元测试拆分为不同的文件并尝试python -m unittest discover
不起作用,这很不方便。测试每个Python文件的单个包装MPI函数并单独运行每个Python文件都可以,但这是我宁愿避免的事情
a
unittest.TestCase
的setUp()
和tearDown()
方法为每个试验方法设置和拆卸提供。您应该期望前者在每个测试方法之前执行,后者在每个测试方法之后执行相反,您似乎希望对类中的整个测试方法集合分别执行一次。为此,您需要setUpClass() and tearDownClass()。或者,如果您定义了多个测试类,那么您可能更喜欢
setUpModule()
和tearDownModule()
或者,您可以创建一个^{} 子类来运行测试,并重写它的
run()
方法以对所有安装和拆卸执行一次相关问题 更多 >
编程相关推荐