从Numba检索生成的LLVM

InS*_*ico 7 python numba

用Numba编译Python函数后,例如:

from numba import jit

@jit
def sum(x, y):
    return x + y
Run Code Online (Sandbox Code Playgroud)

如何检索已编译函数的生成的LLVM代码(作为字符串)?

看起来这在Numba的早期版本中可以通过已编译函数的lfunc属性获得,但这是行不通的。

类似的功能也似乎以转储生成的LLVM程序集的形式存在(在编译过程中)。但是,这似乎也不再起作用-除非我做错了。无论如何,运行终端命令绝对不是理想的选择,因为我真的很喜欢Python中的代码,尽管我知道我可以使用子进程来做到这一点。

这是为了尝试在运行时创建可移植版本的Python代码,并将其进行翻译;我欢迎任何与此有关的建议。

谢谢

rom*_*ric 7

作为记录,从numba版本0.18.0链接到pull request)开始,获取LLVM IR和汇编代码的标准方法是通过inspect_llvminspect_asm调用jitted函数,例如

@jit(nopython=True,nogil=True)
def mysum(a,b):
     return a+b

# First run the function with arguments for the code to get generated
a, b = np.random.rand(10), np.random.rand(10)

# Get the llvm IR
mysum.inspect_llvm()
# Get the assembly code
mysum.inspect_asm()
Run Code Online (Sandbox Code Playgroud)

请注意,返回值采用字典格式。要以可读(源代码)格式显示它,只需执行

for v, k in mysum.inspect_llvm().items():
    print(v, k)
Run Code Online (Sandbox Code Playgroud)

这将输出一长段代码

define i32 @__main__9mysum_...
    ...
    ...
    ...
Run Code Online (Sandbox Code Playgroud)

有趣的是,作为旁注,生成的汇编代码显示上述函数中的LLVM完全展开了for循环

vmovsd  (%r10), %xmm0
vaddsd  (%rcx), %xmm0, %xmm0
vmovsd  %xmm0, -32(%rbx,%rbp)
vmovsd  (%r10), %xmm0
vaddsd  (%rcx), %xmm0, %xmm0
vmovsd  %xmm0, -24(%rbx,%rbp)
vmovsd  (%r10), %xmm0
vaddsd  (%rcx), %xmm0, %xmm0
vmovsd  %xmm0, -16(%rbx,%rbp)
vmovsd  (%r10), %xmm0
vaddsd  (%rcx), %xmm0, %xmm0
vmovsd  %xmm0, -8(%rbx,%rbp)
vmovsd  (%r10), %xmm0
vaddsd  (%rcx), %xmm0, %xmm0
vmovsd  %xmm0, (%rbx,%rbp)
vmovsd  (%r10), %xmm0
vaddsd  (%rcx), %xmm0, %xmm0
vmovsd  %xmm0, 8(%rbx,%rbp)
vmovsd  (%r10), %xmm0
vaddsd  (%rcx), %xmm0, %xmm0
vmovsd  %xmm0, 16(%rbx,%rbp)
vmovsd  (%r10), %xmm0
vaddsd  (%rcx), %xmm0, %xmm0
vmovsd  %xmm0, 24(%rbx,%rbp)
addq    $8, %rdx
addq    $64, %rbx
cmpq    %rdx, %rdi
jne LBB0_48    
Run Code Online (Sandbox Code Playgroud)


小智 5

我不记得这是否是执行此操作的最佳方法,但如果您不介意以不同方式编译该函数,则可以执行以下操作:

from numba.compiler import compile_isolated

# second argument specifies the argument types to the sum function
cfunc = compile_isolated(sum, (types.int64, types.int64))

# get llvm IR as string
llvm_code_str = str(cfunc.llvm_module)
Run Code Online (Sandbox Code Playgroud)

需要指定参数类型,因为函数在知道签名之前不会真正编译(通过显式指定或实际调用函数)。

llvm IR 仍然可以通过设置 NUMBA_DUMP_LLVM=1 环境变量并运行 python 脚本(或使用安装在 Anaconda bin 路径或 Numba 存储库中的 bin 目录中的 numba 命令:numba --dump- llvm 测试.py)。