4

我在使用 numba 时遇到了大量错误。具有讽刺意味的是,正确的结果是在错误之后打印出来的。我正在使用最新的 Anaconda python 并安装了 numba

conda install numba

一次在 Ubuntu 13、64 位和 anaconda 64 位上,在 Windows 64 位上使用 32 位版本的 anaconda。

我要执行的脚本是:

# -*- coding: utf-8 -*-

import math
from numba import autojit

pi = math.pi

@autojit
def sinc(x):
    if x == 0.0:
        return 1.0
    else:
        return math.sin(x*pi)/(pi*x)    


if __name__ == '__main__':
    a = 4.5
    print sinc(a)

我得到的错误是:

DEBUG -- translate:361:translate
; ModuleID = 'tmp.module.__main__.sinc.45bce60'

@PyArray_API = linkonce_odr global i8** inttoptr (i64 140030693224864 to i8**)

define double @__numba_specialized_0___main___2E_sinc(double %x) {
entry:
  %return_value = alloca double
  br label %"if_cond_13:7"

cleanup_label:                                    ; preds = %"else_body_16:8", %"if_body_14:8", %error_label
  %0 = load double* %return_value
  ret double %0

error_label:                                      ; No predecessors!
  store double 0x7FF8000000000000, double* %return_value
  br label %cleanup_label

"if_cond_13:7":                                   ; preds = %entry
  %1 = fcmp oeq double %x, 0.000000e+00
  %2 = icmp ne i1 %1, false
  br i1 %2, label %"if_body_14:8", label %"else_body_16:8"

"if_body_14:8":                                   ; preds = %"if_cond_13:7"
  store double 1.000000e+00, double* %return_value
  br label %cleanup_label

"else_body_16:8":                                 ; preds = %"if_cond_13:7"
  %3 = fmul double %x, 0x400921FB54442D18
  %4 = call double @"numba.math.['double'].sin"(double %3)
  %5 = fmul double 0x400921FB54442D18, %x
  %6 = fdiv double %4, %5
  store double %6, double* %return_value
  br label %cleanup_label
}

declare { i64, i8* }* @Py_BuildValue(i8*, ...)

declare i32 @PyArg_ParseTuple({ i64, i8* }*, i8*, ...)

declare void @PyErr_Clear()

declare double @"numba.math.['double'].sin"(double)

!tbaa = !{!0, !1}

!0 = metadata !{metadata !"root"}
!1 = metadata !{metadata !"char *", metadata !0}


DEBUG -- translate:361:translate
; ModuleID = 'numba_executable_module'

@PyArray_API = linkonce_odr global i8** inttoptr (i64 140030693224864 to i8**)

define void @Py_INCREF({ i64, i8* }* %obj) {
decl:
  %obj1 = alloca { i64, i8* }*
  store { i64, i8* }* %obj, { i64, i8* }** %obj1
  %0 = bitcast { i64, i8* }* %obj to i64*
  %1 = load i64* %0
  %2 = add i64 %1, 1
  store i64 %2, i64* %0
  ret void
}

define void @Py_DECREF({ i64, i8* }* %obj) {
decl:
  %obj1 = alloca { i64, i8* }*
  store { i64, i8* }* %obj, { i64, i8* }** %obj1
  %0 = bitcast { i64, i8* }* %obj to i64*
  %1 = load i64* %0
  %2 = icmp sgt i64 %1, 1
  br i1 %2, label %if.then, label %if.else

if.then:                                          ; preds = %decl
  %3 = add i64 %1, -1
  store i64 %3, i64* %0
  br label %if.end

if.else:                                          ; preds = %decl
  call void @Py_DecRef({ i64, i8* }* %obj)
  br label %if.end

if.end:                                           ; preds = %if.else, %if.then
  ret void
}

declare void @Py_DecRef({ i64, i8* }*)

define void @Py_XINCREF({ i64, i8* }* %obj) {
decl:
  %obj1 = alloca { i64, i8* }*
  store { i64, i8* }* %obj, { i64, i8* }** %obj1
  %0 = ptrtoint { i64, i8* }* %obj to i64
  %1 = icmp ne i64 %0, 0
  br i1 %1, label %if.then, label %if.end

if.then:                                          ; preds = %decl
  %2 = bitcast { i64, i8* }* %obj to i64*
  %3 = load i64* %2
  %4 = add i64 %3, 1
  store i64 %4, i64* %2
  br label %if.end

if.end:                                           ; preds = %if.then, %decl
  ret void
}

define void @Py_XDECREF({ i64, i8* }* %obj) {
decl:
  %obj1 = alloca { i64, i8* }*
  store { i64, i8* }* %obj, { i64, i8* }** %obj1
  %0 = ptrtoint { i64, i8* }* %obj to i64
  %1 = icmp ne i64 %0, 0
  br i1 %1, label %if.then, label %if.end

if.then:                                          ; preds = %decl
  call void @Py_DECREF({ i64, i8* }* %obj)
  br label %if.end

if.end:                                           ; preds = %if.then, %decl
  ret void
}

define i8* @IndexAxis(i8* %data, i64* %in_shape, i64* %in_strides, i64 %src_dim, i64 %index) {
decl:
  %data1 = alloca i8*
  %in_shape2 = alloca i64*
  %in_strides3 = alloca i64*
  %src_dim4 = alloca i64
  %index5 = alloca i64
  %result = alloca i8*
  store i8* %data, i8** %data1
  store i64* %in_shape, i64** %in_shape2
  store i64* %in_strides, i64** %in_strides3
  store i64 %src_dim, i64* %src_dim4
  store i64 %index, i64* %index5
  %0 = load i64** %in_strides3
  %1 = load i64* %src_dim4
  %2 = getelementptr inbounds i64* %0, i64 %1
  %3 = load i64* %2
  %4 = mul i64 %3, %index
  %5 = load i8** %data1
  %6 = getelementptr inbounds i8* %5, i64 %4
  store i8* %6, i8** %result
  ret i8* %6
}

define void @NewAxis(i64* %out_shape, i64* %out_strides, i32 %dst_dim) {
decl:
  %out_shape1 = alloca i64*
  %out_strides2 = alloca i64*
  %dst_dim3 = alloca i32
  store i64* %out_shape, i64** %out_shape1
  store i64* %out_strides, i64** %out_strides2
  store i32 %dst_dim, i32* %dst_dim3
  %0 = load i64** %out_shape1
  %1 = getelementptr inbounds i64* %0, i32 %dst_dim
  store i64 1, i64* %1
  %2 = load i64** %out_strides2
  %3 = load i32* %dst_dim3
  %4 = getelementptr inbounds i64* %2, i32 %3
  store i64 0, i64* %4
  ret void
}

define i32 @Broadcast(i64* %dst_shape, i64* %src_shape, i64* %src_strides, i32 %max_ndim, i32 %ndim) {
decl:
  %dst_shape1 = alloca i64*
  %src_shape2 = alloca i64*
  %src_strides3 = alloca i64*
  %max_ndim4 = alloca i32
  %ndim5 = alloca i32
  %0 = alloca i32
  store i64* %dst_shape, i64** %dst_shape1
  store i64* %src_shape, i64** %src_shape2
  store i64* %src_strides, i64** %src_strides3
  store i32 %max_ndim, i32* %max_ndim4
  store i32 %ndim, i32* %ndim5
  %1 = load i32* %max_ndim4
  %2 = sub i32 %1, %ndim
  store i32 0, i32* %0
  br label %loop.cond

loop.cond:                                        ; preds = %if.end11, %decl
  %3 = load i32* %0
  %4 = load i32* %ndim5
  %5 = icmp slt i32 %3, %4
  br i1 %5, label %loop.body, label %loop.end

loop.body:                                        ; preds = %loop.cond
  %6 = load i64** %src_shape2
  %7 = getelementptr inbounds i64* %6, i32 %3
  %8 = add i32 %3, %2
  %9 = load i64** %dst_shape1
  %10 = getelementptr inbounds i64* %9, i32 %8
  %11 = load i64* %7
  %12 = icmp eq i64 %11, 1
  br i1 %12, label %if.then, label %if.else

loop.end:                                         ; preds = %if.else7, %loop.cond
  %merge = phi i32 [ 1, %loop.cond ], [ 0, %if.else7 ]
  ret i32 %merge

if.then:                                          ; preds = %loop.body
  %13 = load i64** %src_strides3
  %14 = getelementptr inbounds i64* %13, i32 %3
  store i64 0, i64* %14
  br label %if.end11

if.else:                                          ; preds = %loop.body
  %15 = load i64* %10
  %16 = icmp eq i64 %15, 1
  br i1 %16, label %if.then6, label %if.else7

if.then6:                                         ; preds = %if.else
  store i64 %11, i64* %10
  br label %if.end11

if.else7:                                         ; preds = %if.else
  %17 = icmp ne i64 %11, %15
  br i1 %17, label %loop.end, label %if.end11

if.end11:                                         ; preds = %if.else7, %if.then6, %if.then
  %18 = load i32* %0
  %19 = add i32 %18, 1
  store i32 %19, i32* %0
  br label %loop.cond
}

define double @__numba_specialized_0___main___2E_sinc(double %x) {
entry:
  %0 = fcmp oeq double %x, 0.000000e+00
  br i1 %0, label %cleanup_label, label %"else_body_16:8"

cleanup_label:                                    ; preds = %entry, %"else_body_16:8"
  %storemerge = phi double [ %3, %"else_body_16:8" ], [ 1.000000e+00, %entry ]
  ret double %storemerge

"else_body_16:8":                                 ; preds = %entry
  %1 = fmul double %x, 0x400921FB54442D18
  %2 = tail call double @"numba.math.['double'].sin"(double %1)
  %3 = fdiv double %2, %1
  br label %cleanup_label
}

declare double @"numba.math.['double'].sin"(double)

define { i64, i8* }* @__numba_specialized_1_numba_2E_codegen_2E_llvmwrapper_2E___numba_wrapper_sinc(i8* %self, { i64, i8* }* %args) {
entry:
  %objtemp = alloca { i64, i8* }*
  store { i64, i8* }* null, { i64, i8* }** %objtemp, !tbaa !2
  %0 = alloca { i64, i8* }*
  %return_value = alloca { i64, i8* }*
  %1 = call i32 ({ i64, i8* }*, i8*, ...)* @PyArg_ParseTuple({ i64, i8* }* %args, i8* getelementptr inbounds ([2 x i8]* @__STR_0, i32 0, i32 0), { i64, i8* }** %0)
  %2 = icmp eq i32 %1, 0
  br i1 %2, label %cleanup.if.true, label %cleanup.if.end

cleanup_label:                                    ; preds = %no_error, %error_label
  %3 = load { i64, i8* }** %objtemp, !tbaa !2
  call void @Py_XDECREF({ i64, i8* }* %3)
  %4 = load { i64, i8* }** %return_value
  ret { i64, i8* }* %4

error_label:                                      ; preds = %empty1, %empty2, %cleanup.if.true
  store { i64, i8* }* null, { i64, i8* }** %return_value
  %5 = load { i64, i8* }** %return_value, !tbaa !2
  call void @Py_XINCREF({ i64, i8* }* %5)
  br label %cleanup_label

cleanup.if.true:                                  ; preds = %entry
  br label %error_label

cleanup.if.end:                                   ; preds = %entry
  %6 = load { i64, i8* }** %0
  %7 = call double @PyFloat_AsDouble({ i64, i8* }* %6)
  %8 = call double @__numba_specialized_0___main___2E_sinc(double %7)
  br label %empty

empty:                                            ; preds = %cleanup.if.end
  %9 = call i8* @PyErr_Occurred()
  %10 = ptrtoint i8* %9 to i64
  %11 = icmp ne i64 %10, 0
  br i1 %11, label %empty2, label %empty1

empty1:                                           ; preds = %empty
  %12 = call { i64, i8* }* @PyFloat_FromDouble(double %8)
  store { i64, i8* }* %12, { i64, i8* }** %objtemp, !tbaa !2
  %13 = ptrtoint { i64, i8* }* %12 to i64
  %14 = icmp eq i64 %13, 0
  br i1 %14, label %error_label, label %no_error

empty2:                                           ; preds = %empty
  br label %error_label

no_error:                                         ; preds = %empty1
  %15 = load { i64, i8* }** %objtemp, !tbaa !2
  store { i64, i8* }* %15, { i64, i8* }** %return_value
  %16 = load { i64, i8* }** %return_value, !tbaa !2
  call void @Py_XINCREF({ i64, i8* }* %16)
  br label %cleanup_label
}

declare { i64, i8* }* @PyFloat_FromDouble(double)

declare double @PyFloat_AsDouble({ i64, i8* }*)

declare i8* @PyErr_Occurred()

declare { i64, i8* }* @Py_BuildValue(i8*, ...)

declare i32 @PyArg_ParseTuple({ i64, i8* }*, i8*, ...)

declare void @PyErr_Clear()

!tbaa = !{!0, !1, !0, !1, !2}

!0 = metadata !{metadata !"root"}
!1 = metadata !{metadata !"char *", metadata !0}
!2 = metadata !{metadata !"object", metadata !1}

--------------------- Numba Encountered Errors or Warnings ---------------------

^
Warning 0:0: Unreachable code
--------------------------------------------------------------------------------
0.0707355302631

如您所见,最后会显示正确的结果。

有人知道这是什么原因吗?

谢谢!约翰富兰克林爵士

4

1 回答 1

4

这看起来像 LLVM 中间代码。我无法解释最后的警告,但除此之外,看起来你不应该担心它。

我不确定您使用的是哪个版本的 numba,但也许这个旧的(现已关闭的) numba 问题可以帮助您:显然运行 withpython -O可以抑制该输出。

如果没有,您应该尝试找到一种方法来设置调试级别(也许这是在其他地方设置的;您如何运行代码?),这样您就不会在该DEBUG级别运行/编译代码。

更新

经过一番搜索,似乎有些调试级别保留在logging.DEBUG. 您可以通过在导入结束时执行以下操作在脚本中解决此问题:

import logging
import numba
numba.codegen.debug.logger.setLevel(logging.INFO)

不漂亮,也许有更好的方法,但作为一种解决方法,这可能会奏效。

于 2013-10-01T10:10:45.377 回答