用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代码,并将其进行翻译;我欢迎任何与此有关的建议。
谢谢
作为记录,从numba版本0.18.0(链接到pull request)开始,获取LLVM IR和汇编代码的标准方法是通过inspect_llvm和inspect_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)。
| 归档时间: |
|
| 查看次数: |
915 次 |
| 最近记录: |