RISCV平台下scipy/linalg/cython_lapack.so编译及参数错误排查
RISC-V平台SciPy 1.10.0
la.lstsq 调用错误及调试编译方案 问题背景
在RISC-V平台使用SciPy 1.10.0运行最小二乘拟合脚本时触发错误,相同代码在x86 Linux平台无异常。
测试脚本
import scipy import numpy as np import scipy.linalg as la # blas_dep = scipy.show_config(mode='dicts')['Build Dependencies']['blas'] # for key in blas_dep: # print(f"{key}: {blas_dep[key]}") X = np.zeros([90, 1], dtype=np.float64) y = np.array([ -1220.63333333, -1168.63333333, -904.63333333, -618.63333333, -14.63333333, 1331.36666667, 2438.36666667, 4453.36666667, 3460.36666667, 1087.36666667, -966.63333333, -1391.63333333, -1305.63333333, -1210.63333333, -1080.63333333, 795.36666667, 1195.36666667, 1919.36666667, 334.36666667, -1080.63333333, -1338.63333333, -1444.63333333, -1421.63333333, -1276.63333333, -943.63333333, -456.63333333, 639.36666667, 1046.36666667, -532.63333333, -1128.63333333, -1112.63333333, -1264.63333333, -1129.63333333, -758.63333333, 148.36666667, 1235.36666667, 1381.36666667, 629.36666667, -805.63333333, -1190.63333333, -1253.63333333, -1244.63333333, -937.63333333, 133.36666667, 1821.36666667, 5231.36666667, 2764.36666667, -802.63333333, -1234.63333333, -1016.63333333, -1131.63333333, -705.63333333, 104.36666667, 186.36666667, 761.36666667, -63.63333333, -733.63333333, -1190.63333333, -1288.63333333, -1260.63333333, -1020.63333333, -753.63333333, 552.36666667, 1321.36666667, 2941.36666667, 1021.36666667, -1100.63333333, -1416.63333333, -1450.63333333, -1440.63333333, -1430.63333333, -1301.63333333, -1112.63333333, -197.63333333, 2541.36666667, 2005.36666667, -902.63333333, -1384.63333333, -1336.63333333, -1102.63333333, -731.63333333, -182.63333333, 1975.36666667, 5501.36666667, 4823.36666667, 2304.36666667, 346.36666667, -1144.63333333, -1107.63333333, -681.63333333]) la.lstsq(X, y)
错误日志
** On entry to DGELSD parameter number 7 had an illegal value Traceback (most recent call last): File "/home/aa.py", line 25, in <module> la.lstsq(X, y) File "/usr/local/lib/python3.10/dist-packages/scipy/linalg/_basic.py", line 1212, in lstsq lwork, iwork = _compute_lwork(lapack_lwork, m, n, nrhs, cond) File "/usr/local/lib/python3.10/dist-packages/scipy/linalg/lapack.py", line 1004, in _compute_lwork raise ValueError("Internal work array size computation failed: " ValueError: Internal work array size computation failed: -7
经排查,数学函数调用来自cython_lapack.cpython-310-riscv64-linux-gnu.so,疑似包装器参数传递错误,需编译该库并注入调试代码定位根因。
编译cython_lapack模块并注入调试代码的步骤
1. 准备编译环境
- 安装Python 3.10、gcc、gfortran、Cython、NumPy及BLAS/LAPACK开发包(如
openblas-devel) - 若为交叉编译,配置RISC-V交叉编译环境,设置环境变量:
export CC=riscv64-linux-gnu-gcc export FC=riscv64-linux-gnu-gfortran export CXX=riscv64-linux-gnu-g++
2. 获取SciPy 1.10.0源码
- 下载对应版本源码包并解压:
wget https://github.com/scipy/scipy/releases/download/v1.10.0/scipy-1.10.0.tar.gz tar -xzf scipy-1.10.0.tar.gz cd scipy-1.10.0
3. 定位并修改cython_lapack代码
- 进入线性代数模块目录:
cd scipy/linalg - 打开
cython_lapack.pyx,找到调用dgelsd的函数(对应Python层lstsq的底层实现) - 在调用
dgelsd前后添加调试代码,打印关键参数(尤其是错误提示中指出的第7个参数),示例:# 在dgelsd调用前添加 print("DGELSD params: m =", m, ", n =", n, ", nrhs =", nrhs, ", lwork =", lwork) print("Param 7 (rank):", rank) # 根据DGELSD参数列表确认第7个参数对应变量
4. 编译模块
- 在
scipy/linalg目录下运行以下命令编译生成SO文件:python setup.py build_ext --inplace - 编译完成后,目录下会生成
cython_lapack.cpython-310-riscv64-linux-gnu.so
5. 替换并测试
- 将编译生成的SO文件替换系统中SciPy的对应文件:
cp cython_lapack.cpython-310-riscv64-linux-gnu.so /usr/local/lib/python3.10/dist-packages/scipy/linalg/ - 运行原测试脚本,查看调试输出,定位参数非法的具体原因
内容的提问来源于stack exchange,提问作者user24222683
相关产品推荐
相关产品推荐

