简体   繁体   English

使用scipy.weave.inline时出错

[英]Error using scipy.weave.inline

I am using several techniques ( NumPy , Weave , Cython , Numba ) to perform a Python performance benchmark. 我正在使用几种技术( NumPyWeaveCythonNumba )来执行Python性能基准测试。 The code takes two numpy arrays of size NxN and multiplies them element-wise and stores the values in another array C. 该代码采用两个大小为NxN的numpy数组,并将它们按元素相乘并将值存储在另一个数组C中。

My weave.inline() code gives me a scipy.weave.build_tools.CompileError . 我的weave.inline()代码给了我一个scipy.weave.build_tools.CompileError I have created a minimalist piece of code which generates the same error. 我创建了一个极简主义的代码片段,它会产生相同的错误。 Could someone please help? 有人可以帮忙吗?

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()

Two issues. 两个问题。 First, you don't need the line return_val = C . 首先,您不需要return_val = C You are directly manipulating the data in the variable C in your inlined code, so its already available to python and there's no need to explicitly return it to the environment (and trying to do so is causing errors when trying to do the appropriate type conversions). 您正在内联代码中直接操作变量C中的数据,因此它已经可用于python并且不需要显式地将其返回到环境中(并且尝试这样做会导致在尝试执行适当的类型转换时出错) 。 So change your function to: 所以将你的功能改为:

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

Second issue. 第二个问题。 You are comparing i and j (both int s), to N an array of length 1. This also generated an error. 您正在将ij (两个int )与N长度为1的数组进行比较。这也会产生错误。 But if you call your code as: 但是,如果您将代码称为:

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

Three small changes are needed: 需要进行三项小改动:

  • N can't be a 0D-numpy array (it has to be an integer so that i < N works in the C code). N不能是0D-numpy数组(它必须是一个整数,以便i < N在C代码中起作用)。 You should write N = 5000 instead of N = np.array(5000, dtype=np.int) . 您应该写N = 5000而不是N = np.array(5000, dtype=np.int)

  • The C array is being modified in-place so it doesn't have to be returned. C阵列正在进行就地修改,因此不必返回。 I don't know the restrictions on the kind of objects than return_val can handle, but if you try to keep return_val = C; 我不知道对象类型的限制比return_val可以处理,但如果你试图保持return_val = C; it fails compiling: don't know how to convert 'blitz::Array<double, 2>' to 'const py::object&' . 它编译失败: don't know how to convert 'blitz::Array<double, 2>' to 'const py::object&'

  • After that, weave.inline returns None . 之后, weave.inline返回None Keeping the assignment C = weave.inline(... makes the code look confusing, even if it works fine and the array named C will hold the result in the benchmark scope. 保持赋值C = weave.inline(...使代码看起来很混乱,即使它工作正常,名为C的数组也会将结果保存在benchmark范围内。

This is the end result: 这是最终结果:

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')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM