我有兴趣为我们的几个OpenMDAO组件添加底层并行性。这些组件中的大部分代码都是用Fortran编写的。 Fortran代码包装在python中,然后在OpenMDAO中用作python模块。我想使用OpenMP或OpenMPI并行运行这些Fortran代码。我们已经计划使用OpenMDAO的内置并行功能,因此这将是第二层并行性。这可行吗?如果是这样,你有一个适合OpenMDAO的推荐方法吗?
答案 0 :(得分:2)
首先,我将解决有关OpenMP的问题。目前OpenMDAO本身并不使用OpenMP,我们也没有任何计划可以很快改变它。这意味着,我们框架并不真正了解或关心您是否碰巧在Fortran代码中使用它。请随意关注MPI + OpenMP代码的所有常规警告!
如果您想在组件本身中使用MPI并行性,OpenMDAO直接支持。我们有fairly simple tutorial这种情况,组件本身想要多个处理器。本教程的显着特性是组件向框架请求多个处理器:
def get_req_procs(self):
"""
min/max number of cpus that this component can use
"""
return (1,self.size)
在这种情况下,组件将接受1个proc中的任何位置,直到其数组中的元素数。在您的情况下,您可能希望将其限制为单个值,在这种情况下,您可以返回单个整数。
另一个值得注意的部分是:
def setup_distrib_idxs(self):
"""
specify the local sizes of the variables and which specific indices this specific
distributed component will handle. Indices do NOT need to be sequential or
contiguous!
"""
comm = self.comm
rank = comm.rank
#NOTE: evenly_distrib_idxs is a helper function to split the array up as evenly as possible
sizes, offsets = evenly_distrib_idxs(comm.size, self.size)
local_size, local_offset = sizes[rank], offsets[rank]
self.local_size = int(local_size)
start = local_offset
end = local_offset + local_size
self.set_var_indices('x', val=np.zeros(local_size, float),
src_indices=np.arange(start, end, dtype=int))
self.set_var_indices('y', val=np.zeros(local_size, float),
src_indices=np.arange(start, end, dtype=int))
此代码告诉框架您的分布式数据如何在多个过程中分离。从一个实现到下一个实现,这些方法的细节将有很大不同。在某些情况下,您可能会让所有过程都拥有所有数据。在其他(如此)中,您将在procs中均匀分布数据。在其他情况下,您可能拥有全局数据和分布式数据的组合。
如果您计划仅使用OpenMP,您可能会共享所有进程中的所有数据,但仍然请求超过1个proc。这样,您可以确保OpenMDAO为您的comp分配了足够的proc,以便在多线程上下文中使用它。您将获得一个可以使用的comm对象来分配任务。
如果您计划使用纯粹的MPI,则可能(但不确定)您将使用分布式数据。您仍然希望请求超过1个proc,但您还必须分割数据。
如果您决定使用OpenMP和MPI,则可能需要分布式和共享数据的某种组合。