使用scipy.weave.inline时出现错误

3

我正在使用多种技术(NumPyWeaveCythonNumba)进行Python性能基准测试。该代码需要对大小为NxN的两个numpy数组进行元素乘法,并将结果存储在另一个数组C中。

我的weave.inline()代码出现了scipy.weave.build_tools.CompileError错误。我已经创建了一个最小化的代码,它产生了相同的错误。请有人帮帮我吗?

import time

import numpy as np
from scipy import weave
from scipy.weave import converters


def benchmark():

    N = np.array(5000, dtype=np.int)

    A = np.random.rand(N, N)
    B = np.random.rand(N, N)
    C = np.zeros([N, N], dtype=float)

    t = time.clock()
    weave_inline_loop(A, B, C, N)
    print time.clock() - t


def weave_inline_loop(A, B, C, N):
    code = """
           int i, j;
           for (i = 0; i < N; ++i)
           {
               for (j = 0; j < N; ++j)
               {
                   C(i, j) = A(i, j) * B(i, j);
               }
           }
           return_val = C;
           """
    C = weave.inline(code, ['A', 'B', 'C', 'N'], type_converters=converters.blitz, compiler='gcc')

benchmark()
2个回答

3

两个问题。首先,您不需要使用return_val = C这一行代码。在您的内联代码中直接操作变量C中的数据,因此它已经可用于Python,没有必要显式地将其返回到环境中(尝试这样做会在尝试进行适当的类型转换时导致错误)。因此,请将您的函数更改为:

def weave_inline_loop(A, B, C, N):
    code = """
           int i, j;
           for (i = 0; i < N; ++i)
           {
               for (j = 0; j < N; ++j)
               {
                   C(i, j) = A(i, j) * B(i, j);
               }
           }
           """
    weave.inline(code, ['A', 'B', 'C', 'N'], type_converters=converters.blitz, compiler='gcc')
    return C

第二个问题。您比较了i和j(都是int类型)与长度为1的N数组。这也生成了一个错误。但如果您按以下方式调用代码:

def benchmark():

    N = np.array(5000, dtype=np.int)

    A = np.random.rand(N, N)
    B = np.random.rand(N, N)
    C = np.zeros([N, N], dtype=float)

    t = time.clock()
    print weave_inline_loop(A, B, C, int(N)) 
    # I added a print statement so you can see that C is being 
    # populated with the new 2d array
    print time.clock() - t

3
需要三个小改动:
  • N 不能是 0D-numpy 数组(它必须是整数,以便 C 代码中的 i < N 能够使用)。您应该写 N = 5000 而不是 N = np.array(5000, dtype=np.int)

  • C 数组被原地修改,因此不必返回。我不知道 return_val 可以处理哪种对象的限制,但如果尝试保留 return_val = C;,则编译失败:don't know how to convert ‘blitz::Array<double, 2>’ to ‘const py::object&’

  • 之后,weave.inline 返回 None。即使代码正常工作且名为 C 的数组将在 benchmark 范围内保存结果,保留赋值语句 C = weave.inline(... 会让代码看起来令人困惑。

这是最终结果:

import time
import numpy as np
from scipy import weave
from scipy.weave import converters


def benchmark():
    N = 5000

    A = np.random.rand(N, N)
    B = np.random.rand(N, N)
    C = np.zeros([N, N], dtype=float)

    t = time.clock()
    weave_inline_loop(A, B, C, N)
    print time.clock() - t


def weave_inline_loop(A, B, C, N):
    code = """
           int i, j;
           for (i = 0; i < N; ++i)
           {
               for (j = 0; j < N; ++j)
               {
                   C(i, j) = A(i, j) * B(i, j);
               }
           }
           """
    weave.inline(code, ['A', 'B', 'C', 'N'], type_converters=converters.blitz, compiler='gcc')

+1 - 几乎相同的答案。我们方法之间唯一的区别是,我认为值得展示C从内联调用中返回结果;而N则保留了他的格式,只是在调用前将其强制转换为int类型。 - dr jimbob
几乎同时发生 (+1)! - jorgeca

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