我正在尝试通过 pyspark 提交并使用 python 模块,但遇到导入错误。一切在本地都运行良好,但将作业提交给远程工作人员时问题就出现了。
我尝试使用的模块对一些 .so 文件有一个 import 语句,这些文件是我用 f2py 创建的编译 fortran 代码的函数。我尝试使用 sc.addFile(.zip) 命令以及 sc.addPyFile(.zip) 提交 .zip 中的所有文件。通过这种方式,我可以访问所有 .py 文件,但找不到 .so 文件。通过手动列出所有文件以及使用 Spark-submit 时使用 --files 命令也会发生同样的情况。
有什么方法可以发送 .so 文件来使用吗?或者,既然我有 Makefile,我可以在远程机器上编译它们吗?
由于洞包不是很重,是否可以将其复制到远程计算机上,然后告诉 pyspark 访问该文件夹?
远程计算机通过 ssh 连接,因此我可以在那里发送和移动文件。 文件结构如下所示:
.
├── libs
│ ├── FortranFunctions.cpython-36m-x86_64-linux-gnu.so
│ ├── libCPU.py
│ ├── libGPU.py
│ └── lib.py
├── LICENSE
├── main.py
├── Makefile
├── README.md
├── src
│ └── FortranFunctions.f90
└── variables.py
正如您在 /libs 文件夹中看到的,我放置了一些使用 Spark 时可以访问的 .py 文件和我无法导入的 .so 文件。
根据要求,我添加了代码:
src/ 文件夹中的文件 fortranFunctions.f90 是我在 python 中使用的 fortran 子例程的源代码。
Python 中的代码只是
from libs import FortranFunctions
,并且这个 在本地 可以工作。
用于提交作业的代码如下所示:
from pyspark.sql import SparkSession
from main import *
spark = SparkSession.builder.appName('pySiPM').getOrCreate()
sc = spark.sparkContext
sc.addFile('files.zip')
data = []
for i in range(20):
times = np.ones(np.random.poisson(5))*30
data.append(times)
res = sc.parallelize(data).map(SiPM).collect()
spark 现在不支持此功能,但是https://issues.apache.org/jira/browse/SPARK-26827
中提到了一个解决方法解决方案:使用 py-files 和 archives 选项传递相同的存档。
例如,可以使用以下命令:
spark-submit --pyfiles /your/pyfile/xxx.py --archives /your/sofile/xxx.so
我在本地进行了测试,这可以在我这边工作,我的so文件来自SWIG导出库。