在OpenMDAO中使用具有底层并行性的代码

时间:2015-10-26 20:20:37

标签: parallel-processing openmdao

我有兴趣为我们的几个OpenMDAO组件添加底层并行性。这些组件中的大部分代码都是用Fortran编写的。 Fortran代码包装在python中,然后在OpenMDAO中用作python模块。我想使用OpenMP或OpenMPI并行运行这些Fortran代码。我们已经计划使用OpenMDAO的内置并行功能,因此这将是第二层并行性。这可行吗?如果是这样,你有一个适合OpenMDAO的推荐方法吗?

1 个答案:

答案 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,则可能需要分布式和共享数据的某种组合。