You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Numba @jit处理Numpy数组时触发错误,请求技术帮助

解决Numba nopython模式下修改全局数组触发的InternalError问题

问题原因

在Numba的nopython=True编译模式下,全局变量会被默认标记为只读,无法在函数内部直接修改。你代码中定义的array1和array2是全局数组,在jit修饰的函数里直接对其赋值,就触发了这个只读限制的错误。

解决方案

方案1:将数组作为函数参数传递(推荐)

这是Numba官方推荐的方式,nopython模式对函数参数的读写支持更完善,也更利于编译器优化。修改后的代码如下:

#!/usr/bin/Python

import numpy as np
from numba import jit

SIZE = 1000
array1 = np.full((SIZE, SIZE), 0)
array2 = np.full((SIZE, SIZE), 0)

@jit(nopython=True)
def fun(arr1, arr2):
    # 注意:nopython模式下禁用print,否则会大幅降低性能,测试时建议移除
    for i in range(1000):
        for j in range(1000):
            arr1[i,j] = i+j
            arr2[i,j] = i-j
            arr1[i,j] = arr2[j,i]

            for k in range(1000):
                arr1[i,j] = i+j
                arr2[i,j] = i-j
                arr1[i,j] = arr2[j,i]

                for l in range(1000):
                    arr1[i,j] = i+j
                    arr2[i,j] = i-j
                    arr1[i,j] = arr2[j,i]

# 调用函数时传入数组
fun(array1, array2)
# 可按需打印部分结果验证:print(array1[:5, :5])

方案2:使用globalref声明全局变量(不推荐)

如果必须使用全局变量,可以通过numba.globalref在函数内部获取可写的全局变量引用,但这种方式会削弱Numba的优化能力,且代码可读性差,仅作备选:

#!/usr/bin/Python

import numpy as np
from numba import jit, globalref

SIZE = 1000
array1 = np.full((SIZE, SIZE), 0)
array2 = np.full((SIZE, SIZE), 0)

@jit(nopython=True)
def fun():
    arr1 = globalref('array1')
    arr2 = globalref('array2')
    
    for i in range(1000):
        for j in range(1000):
            arr1[i,j] = i+j
            arr2[i,j] = i-j
            arr1[i,j] = arr2[j,i]

            for k in range(1000):
                arr1[i,j] = i+j
                arr2[i,j] = i-j
                arr1[i,j] = arr2[j,i]

                for l in range(1000):
                    arr1[i,j] = i+j
                    arr2[i,j] = i-j
                    arr1[i,j] = arr2[j,i]

fun()

额外优化建议

  • 用range替代np.arange作为循环索引:Numba对原生range的优化更好,能生成更高效的机器码。
  • 移除无意义的重复赋值:你代码中多次对同一数组元素重复赋值(如arr1[i,j]被多次覆盖),实际性能测试时建议替换为有实际计算逻辑的代码,否则测试结果不具备参考性。
  • 禁用print:nopython模式下调用print会强制切换到对象模式,完全失去Numba的性能优势,性能测试时务必移除。

内容的提问来源于stack exchange,提问作者Qba Liu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 16:12:56