使用NumPy数组操作与Numba的@guvectorize

3

最近我一直在尝试使用Numba,但有些事情我仍然无法理解:

在普通的Python函数中使用NumPy数组时,你可以像这样做:

# Subtracts two NumPy arrays and returns an array as the result
def sub(a, b):
    res = a - b
    return res

然而,当你使用Numba的@guvectorize装饰器时,代码如下:

# Subtracts two NumPy arrays and returns an array as the result
@guvectorize(['void(float32[:], float32[:], float32[:])'],'(n),(n)->(n)')
def subT(a, b, res):
    res = a - b

结果甚至不正确。更糟糕的是,有时会抱怨“在[参数]中无效使用[数学运算符]”。
我很困惑。即使我尝试这样做:
# Subtracts two NumPy arrays and returns an array as the result
@guvectorize(['void(float32[:], float32[:], float32[:])'],'(n),(n)->(n)')
def subTt(a, b, res):
    res = np.subtract(a,b)

结果仍然不正确。考虑到 这应该是一个支持的数学运算符,我不明白为什么它不起作用。
我知道标准的方法是这样的:
# Subtracts two NumPy arrays and returns an array as the result
@guvectorize(['void(float32[:], float32[:], float32[:])'],'(n),(n)->(n)')
def subTtt(a, b, res):
    for i in range(a.shape[0]):
        res[i] = a[i] - b[i]

这确实按照预期工作。

但是我的方法有什么问题吗?

P / S 这只是一个微不足道的例子,用于解释我的问题,我实际上并不打算仅使用@guvectorize减去数组:P P / P / S 我怀疑与将数组复制到GPU内存的方式有关,但我不确定...... P / P / P / S 这个看起来相关,但这里的函数仅在单个线程上运行...

1个回答

2
正确的写法是:

这样写:

@guvectorize(['void(float32[:], float32[:], float32[:])'],'(n),(n)->(n)')
def subT(a, b, res):
    res[:] = a - b

你尝试的方法不起作用,是由于Python语法的限制,而不是numba特有的问题。 name = expr将名称的值重新绑定到expr,它永远无法改变名称的原始值,就像C++引用一样。 name[] = expr调用(本质上),name.__setitem__,可以用来修改名称,就像numpy数组那样,空切片[:]指整个数组。

请原谅我的问题,但是为什么“正常”的Python函数可以工作呢? - umop apisdn
它能够工作是因为你返回了 res,而在 gufunc 中,你需要改变输入。 - chrisb
嗯,好的,谢谢!看来我仍然需要学习更多的Python。 - umop apisdn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接