Debugging the compilation pipeline

Consider the following two examples. numba_dpex/examples/debug/simple_sum.py:

15
16
17global_size = 10
18N = global_size
19
20a = np.array(np.random.random(N), dtype=np.float32)
21b = np.array(np.random.random(N), dtype=np.float32)
22c = np.ones_like(a)
23
24data_parallel_sum[ndpx.Range(global_size)](a, b, c)
25
26print("Done...")

Example of default Numba execution on a CPU:

15
16def main():
17    foo(987)
18
19
20if __name__ == "__main__":
21    main()
22    print("Done ...")

Getting the DWARF from binary file

In order to get the DWARF information from a specific kernel, just enable IGC_ShaderDumpEnable variable. IGC will write number of dumps into /tmp/IntelIGC.

export IGC_ShaderDumpEnable=1

To read the DWARF of a kernel, a copy of the IGC generated kernel binary is needed. Run the Python script in a GDB debugger mode, and set a breakpoint in the kernel:

$ export NUMBA_OPT=1 $ gdb-oneapi -q --args python simple_sum.py (gdb) break
simple_sum.py:22 (gdb) run

Once the breakpoint is hit, the kernel has been generated and offloaded. At that point, the IGFX driver (i.e. our GDB debugger driver) has copied the kernel into a file, and saved it at /tmp. All files saved at /tmp/IntelIGC/python_xxx/

Dump generated DWARF from the kernel binary (elf) via llvm-dwarfdump tool:

llvm-dwarfdump xxx.elf

Getting the DWARF from Numba assembly (for njit)

Setting Numba environment variable NUMBA_DUMP_ASSEMBLY dumps the native assembly code of compiled functions.

NUMBA_DUMP_ASSEMBLY=1 python njit-basic.py > njit-basic-asm.txt

Clear file from prints and unrecognized characters (-, =, !, ) Get compiled from assembler:

as -o o njit-basic-asm.txt

Get dwarf with objdump:

objdump -W o > o_dwarf

See also: