我有一个用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__'
是否可以修改我的代码来解决问题? 谢谢。
答案 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()方法。