使用Fortran库进行Spark并行化

时间:2018-07-17 13:11:38

标签: python-3.x pyspark gfortran

我有一个用Fortran编写的模型(无法修改),该模型生成一个由两个函数组成的共享库:

  • load_model:从文本文件加载所有模型设置,分配数组等。

  • run_model:获取模型参数(特定于每个模拟)并使用先前指定的设置运行模型

我已经设法使用gfort2py(https://github.com/rjfarmer/gfort2py)将库包装在python中(f2py无法正常工作),现在我在Python中有一个Model类,该类具有加载和运行功能。

代码如下:

class Model():
    def load(self):
        self.model = gfort2py.fFort(lib_name, mod_name)
        self.model.load_model()

    def run(self, parameters):
        return self.model.run_model(parameters)

请注意,实际代码要复杂一些,但我认为在此处添加复杂性并不重要。

现在,当我在没有并行化的情况下在Python中运行模型

mod = Model()
mod.load()
mod.run(parameters)

一切正常。

当我尝试使用Spark并行化代码时出现问题。代码看起来像

mod = Model()
mod.load()
sc = SparkContext()
RDD = sc.parallelize(pars, 4)
mod_RDD = RDD.map(mod.run)
res = mod_RDD.collect()

当我尝试运行此程序时,我会得到

AttributeError: 'builtin_function_or_method' object has no attribute '__code__'

是否可以修改我的代码来解决问题? 谢谢。

1 个答案:

答案 0 :(得分:0)

尽管我遇到了其他问题,但事情并非如此简单,但我无法重现您收到的确切错误消息。但是,似乎有效的一件事是将map函数添加到您的Model()类:

class Model():
    def load(self):
        self.model = gfort2py.fFort(lib_name, mod_name)
        self.model.load_model()

    def run(self, parameters):
        return self.model.run_model(parameters)

    def map(self, RDD):
        return RDD.map(self.run)

然后

mod = Model()
mod.load()
sc = SparkContext()
RDD = sc.parallelize(pars, 4)
mod_RDD = mod.map(RDD)
res = mod_RDD.collect()

请参见https://spark.apache.org/docs/2.2.0/rdd-programming-guide.html和有关传递函数的部分。

这是使用python 3.6.6,pyspark 2.3.1和gfort2py以及当前未发布的e42b2fb版本。如果未发布的gfort2py版本适合您,那么我将发布一个新版本。问题的一部分是,spark需要在map()中运行的代码是可挑选的,gort2py e42b2fb使部分东西可以挑选,但是除非在您的代码中重复了它,否则您将失去在fortran方面所做的任何初始化,在load_model()中run()方法。