aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/rust.yml54
-rw-r--r--.gitignore46
-rw-r--r--.gitmodules7
-rw-r--r--Cargo.toml15
-rw-r--r--GeekBench_5_2_3.svg1
-rw-r--r--LICENSE-APACHE176
-rw-r--r--LICENSE-MIT23
-rw-r--r--README.md97
-rw-r--r--ext/detours/.github/ISSUE_TEMPLATE/bug-report.md (renamed from .github/ISSUE_TEMPLATE/bug-report.md)0
-rw-r--r--ext/detours/.github/ISSUE_TEMPLATE/question.md (renamed from .github/ISSUE_TEMPLATE/question.md)0
-rw-r--r--ext/detours/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md (renamed from .github/PULL_REQUEST_TEMPLATE/pull_request_template.md)0
-rw-r--r--ext/detours/.github/codeql/codeql-config.yml (renamed from .github/codeql/codeql-config.yml)0
-rw-r--r--ext/detours/.github/workflows/main.yml (renamed from .github/workflows/main.yml)0
-rw-r--r--ext/detours/.gitignore41
-rw-r--r--ext/detours/CREDITS.TXT (renamed from CREDITS.TXT)0
-rw-r--r--ext/detours/LICENSE.md (renamed from LICENSE.md)0
-rw-r--r--ext/detours/Makefile (renamed from Makefile)0
-rw-r--r--ext/detours/README.md56
-rw-r--r--ext/detours/samples/Makefile (renamed from samples/Makefile)0
-rw-r--r--ext/detours/samples/README.TXT (renamed from samples/README.TXT)0
-rw-r--r--ext/detours/samples/comeasy/Makefile (renamed from samples/comeasy/Makefile)0
-rw-r--r--ext/detours/samples/comeasy/comeasy.cpp (renamed from samples/comeasy/comeasy.cpp)0
-rw-r--r--ext/detours/samples/comeasy/wrotei.cpp (renamed from samples/comeasy/wrotei.cpp)0
-rw-r--r--ext/detours/samples/comeasy/wrotei.rc (renamed from samples/comeasy/wrotei.rc)0
-rw-r--r--ext/detours/samples/commem/Makefile (renamed from samples/commem/Makefile)0
-rw-r--r--ext/detours/samples/commem/commem.cpp (renamed from samples/commem/commem.cpp)0
-rw-r--r--ext/detours/samples/common.mak (renamed from samples/common.mak)0
-rw-r--r--ext/detours/samples/cping/Makefile (renamed from samples/cping/Makefile)0
-rw-r--r--ext/detours/samples/cping/ReadMe.Txt (renamed from samples/cping/ReadMe.Txt)0
-rw-r--r--ext/detours/samples/cping/cping.cpp (renamed from samples/cping/cping.cpp)0
-rw-r--r--ext/detours/samples/cping/cping.dat (renamed from samples/cping/cping.dat)0
-rw-r--r--ext/detours/samples/cping/iping.idl (renamed from samples/cping/iping.idl)0
-rw-r--r--ext/detours/samples/disas/Makefile (renamed from samples/disas/Makefile)0
-rw-r--r--ext/detours/samples/disas/arm.asm (renamed from samples/disas/arm.asm)0
-rw-r--r--ext/detours/samples/disas/disas.cpp (renamed from samples/disas/disas.cpp)0
-rw-r--r--ext/detours/samples/disas/ia64.asm (renamed from samples/disas/ia64.asm)0
-rw-r--r--ext/detours/samples/disas/unk.cpp (renamed from samples/disas/unk.cpp)0
-rw-r--r--ext/detours/samples/disas/x64.asm (renamed from samples/disas/x64.asm)0
-rw-r--r--ext/detours/samples/disas/x86.cpp (renamed from samples/disas/x86.cpp)0
-rw-r--r--ext/detours/samples/dtest/Makefile (renamed from samples/dtest/Makefile)0
-rw-r--r--ext/detours/samples/dtest/NORMAL_IA64.TXT (renamed from samples/dtest/NORMAL_IA64.TXT)0
-rw-r--r--ext/detours/samples/dtest/NORMAL_X64.TXT (renamed from samples/dtest/NORMAL_X64.TXT)0
-rw-r--r--ext/detours/samples/dtest/NORMAL_X86.TXT (renamed from samples/dtest/NORMAL_X86.TXT)0
-rw-r--r--ext/detours/samples/dtest/dtarge.cpp (renamed from samples/dtest/dtarge.cpp)0
-rw-r--r--ext/detours/samples/dtest/dtarge.h (renamed from samples/dtest/dtarge.h)0
-rw-r--r--ext/detours/samples/dtest/dtarge.rc (renamed from samples/dtest/dtarge.rc)0
-rw-r--r--ext/detours/samples/dtest/dtest.cpp (renamed from samples/dtest/dtest.cpp)0
-rw-r--r--ext/detours/samples/dumpe/Makefile (renamed from samples/dumpe/Makefile)0
-rw-r--r--ext/detours/samples/dumpe/dumpe.cpp (renamed from samples/dumpe/dumpe.cpp)0
-rw-r--r--ext/detours/samples/dumpi/Makefile (renamed from samples/dumpi/Makefile)0
-rw-r--r--ext/detours/samples/dumpi/dumpi.cpp (renamed from samples/dumpi/dumpi.cpp)0
-rw-r--r--ext/detours/samples/dynamic_alloc/Makefile (renamed from samples/dynamic_alloc/Makefile)0
-rw-r--r--ext/detours/samples/dynamic_alloc/main.cpp (renamed from samples/dynamic_alloc/main.cpp)0
-rw-r--r--ext/detours/samples/dynamic_alloc/x64.asm (renamed from samples/dynamic_alloc/x64.asm)0
-rw-r--r--ext/detours/samples/dynamic_alloc/x86.asm (renamed from samples/dynamic_alloc/x86.asm)0
-rw-r--r--ext/detours/samples/echo/Makefile (renamed from samples/echo/Makefile)0
-rw-r--r--ext/detours/samples/echo/echofx.cpp (renamed from samples/echo/echofx.cpp)0
-rw-r--r--ext/detours/samples/echo/echofx.rc (renamed from samples/echo/echofx.rc)0
-rw-r--r--ext/detours/samples/echo/echonul.cpp (renamed from samples/echo/echonul.cpp)0
-rw-r--r--ext/detours/samples/echo/main.cpp (renamed from samples/echo/main.cpp)0
-rw-r--r--ext/detours/samples/einst/Makefile (renamed from samples/einst/Makefile)0
-rw-r--r--ext/detours/samples/einst/edll1x.cpp (renamed from samples/einst/edll1x.cpp)0
-rw-r--r--ext/detours/samples/einst/edll2x.cpp (renamed from samples/einst/edll2x.cpp)0
-rw-r--r--ext/detours/samples/einst/edll3x.cpp (renamed from samples/einst/edll3x.cpp)0
-rw-r--r--ext/detours/samples/einst/einst.cpp (renamed from samples/einst/einst.cpp)0
-rw-r--r--ext/detours/samples/excep/Makefile (renamed from samples/excep/Makefile)0
-rw-r--r--ext/detours/samples/excep/excep.cpp (renamed from samples/excep/excep.cpp)0
-rw-r--r--ext/detours/samples/excep/firstexc.cpp (renamed from samples/excep/firstexc.cpp)0
-rw-r--r--ext/detours/samples/excep/firstexc.h (renamed from samples/excep/firstexc.h)0
-rw-r--r--ext/detours/samples/findfunc/Makefile (renamed from samples/findfunc/Makefile)0
-rw-r--r--ext/detours/samples/findfunc/extend.cpp (renamed from samples/findfunc/extend.cpp)0
-rw-r--r--ext/detours/samples/findfunc/extend.rc (renamed from samples/findfunc/extend.rc)0
-rw-r--r--ext/detours/samples/findfunc/findfunc.cpp (renamed from samples/findfunc/findfunc.cpp)0
-rw-r--r--ext/detours/samples/findfunc/symtest.cpp (renamed from samples/findfunc/symtest.cpp)0
-rw-r--r--ext/detours/samples/findfunc/target.cpp (renamed from samples/findfunc/target.cpp)0
-rw-r--r--ext/detours/samples/findfunc/target.h (renamed from samples/findfunc/target.h)0
-rw-r--r--ext/detours/samples/findfunc/target.rc (renamed from samples/findfunc/target.rc)0
-rw-r--r--ext/detours/samples/impmunge/Makefile (renamed from samples/impmunge/Makefile)0
-rw-r--r--ext/detours/samples/impmunge/impmunge.cpp (renamed from samples/impmunge/impmunge.cpp)0
-rw-r--r--ext/detours/samples/member/Makefile (renamed from samples/member/Makefile)0
-rw-r--r--ext/detours/samples/member/member.cpp (renamed from samples/member/member.cpp)0
-rw-r--r--ext/detours/samples/opengl/Makefile (renamed from samples/opengl/Makefile)0
-rw-r--r--ext/detours/samples/opengl/ogldet.cpp (renamed from samples/opengl/ogldet.cpp)0
-rw-r--r--ext/detours/samples/opengl/ogldet.rc (renamed from samples/opengl/ogldet.rc)0
-rw-r--r--ext/detours/samples/opengl/testogl.cpp (renamed from samples/opengl/testogl.cpp)0
-rw-r--r--ext/detours/samples/region/Makefile (renamed from samples/region/Makefile)0
-rw-r--r--ext/detours/samples/region/region.cpp (renamed from samples/region/region.cpp)0
-rw-r--r--ext/detours/samples/setdll/Makefile (renamed from samples/setdll/Makefile)0
-rw-r--r--ext/detours/samples/setdll/setdll.cpp (renamed from samples/setdll/setdll.cpp)0
-rw-r--r--ext/detours/samples/simple/Makefile (renamed from samples/simple/Makefile)0
-rw-r--r--ext/detours/samples/simple/simple.cpp (renamed from samples/simple/simple.cpp)0
-rw-r--r--ext/detours/samples/simple/simple.rc (renamed from samples/simple/simple.rc)0
-rw-r--r--ext/detours/samples/simple/sleep5.cpp (renamed from samples/simple/sleep5.cpp)0
-rw-r--r--ext/detours/samples/slept/Makefile (renamed from samples/slept/Makefile)0
-rw-r--r--ext/detours/samples/slept/NORMAL_IA64.TXT (renamed from samples/slept/NORMAL_IA64.TXT)0
-rw-r--r--ext/detours/samples/slept/NORMAL_X64.TXT (renamed from samples/slept/NORMAL_X64.TXT)0
-rw-r--r--ext/detours/samples/slept/NORMAL_X86.TXT (renamed from samples/slept/NORMAL_X86.TXT)0
-rw-r--r--ext/detours/samples/slept/dslept.cpp (renamed from samples/slept/dslept.cpp)0
-rw-r--r--ext/detours/samples/slept/dslept.rc (renamed from samples/slept/dslept.rc)0
-rw-r--r--ext/detours/samples/slept/sleepbed.cpp (renamed from samples/slept/sleepbed.cpp)0
-rw-r--r--ext/detours/samples/slept/sleepnew.cpp (renamed from samples/slept/sleepnew.cpp)0
-rw-r--r--ext/detours/samples/slept/sleepold.cpp (renamed from samples/slept/sleepold.cpp)0
-rw-r--r--ext/detours/samples/slept/slept.cpp (renamed from samples/slept/slept.cpp)0
-rw-r--r--ext/detours/samples/slept/slept.h (renamed from samples/slept/slept.h)0
-rw-r--r--ext/detours/samples/slept/slept.rc (renamed from samples/slept/slept.rc)0
-rw-r--r--ext/detours/samples/slept/verify.cpp (renamed from samples/slept/verify.cpp)0
-rw-r--r--ext/detours/samples/syelog/Makefile (renamed from samples/syelog/Makefile)0
-rw-r--r--ext/detours/samples/syelog/sltest.cpp (renamed from samples/syelog/sltest.cpp)0
-rw-r--r--ext/detours/samples/syelog/sltestp.cpp (renamed from samples/syelog/sltestp.cpp)0
-rw-r--r--ext/detours/samples/syelog/syelog.cpp (renamed from samples/syelog/syelog.cpp)0
-rw-r--r--ext/detours/samples/syelog/syelog.h (renamed from samples/syelog/syelog.h)0
-rw-r--r--ext/detours/samples/syelog/syelogd.cpp (renamed from samples/syelog/syelogd.cpp)0
-rw-r--r--ext/detours/samples/talloc/Makefile (renamed from samples/talloc/Makefile)0
-rw-r--r--ext/detours/samples/talloc/NORMAL_IA64.TXT (renamed from samples/talloc/NORMAL_IA64.TXT)0
-rw-r--r--ext/detours/samples/talloc/NORMAL_X64.TXT (renamed from samples/talloc/NORMAL_X64.TXT)0
-rw-r--r--ext/detours/samples/talloc/talloc.cpp (renamed from samples/talloc/talloc.cpp)0
-rw-r--r--ext/detours/samples/talloc/tdll1x.cpp (renamed from samples/talloc/tdll1x.cpp)0
-rw-r--r--ext/detours/samples/talloc/tdll2x.cpp (renamed from samples/talloc/tdll2x.cpp)0
-rw-r--r--ext/detours/samples/talloc/tdll3x.cpp (renamed from samples/talloc/tdll3x.cpp)0
-rw-r--r--ext/detours/samples/talloc/tdll4x.cpp (renamed from samples/talloc/tdll4x.cpp)0
-rw-r--r--ext/detours/samples/talloc/tdll5x.cpp (renamed from samples/talloc/tdll5x.cpp)0
-rw-r--r--ext/detours/samples/talloc/tdll6x.cpp (renamed from samples/talloc/tdll6x.cpp)0
-rw-r--r--ext/detours/samples/talloc/tdll7x.cpp (renamed from samples/talloc/tdll7x.cpp)0
-rw-r--r--ext/detours/samples/talloc/tdll8x.cpp (renamed from samples/talloc/tdll8x.cpp)0
-rw-r--r--ext/detours/samples/talloc/tdll9x.cpp (renamed from samples/talloc/tdll9x.cpp)0
-rw-r--r--ext/detours/samples/traceapi/Makefile (renamed from samples/traceapi/Makefile)0
-rw-r--r--ext/detours/samples/traceapi/_win32.cpp (renamed from samples/traceapi/_win32.cpp)0
-rw-r--r--ext/detours/samples/traceapi/testapi.cpp (renamed from samples/traceapi/testapi.cpp)0
-rw-r--r--ext/detours/samples/traceapi/trcapi.cpp (renamed from samples/traceapi/trcapi.cpp)0
-rw-r--r--ext/detours/samples/traceapi/trcapi.rc (renamed from samples/traceapi/trcapi.rc)0
-rw-r--r--ext/detours/samples/tracebld/Makefile (renamed from samples/tracebld/Makefile)0
-rw-r--r--ext/detours/samples/tracebld/tracebld.cpp (renamed from samples/tracebld/tracebld.cpp)0
-rw-r--r--ext/detours/samples/tracebld/tracebld.h (renamed from samples/tracebld/tracebld.h)0
-rw-r--r--ext/detours/samples/tracebld/trcbld.cpp (renamed from samples/tracebld/trcbld.cpp)0
-rw-r--r--ext/detours/samples/tracebld/trcbld.rc (renamed from samples/tracebld/trcbld.rc)0
-rw-r--r--ext/detours/samples/tracelnk/Makefile (renamed from samples/tracelnk/Makefile)0
-rw-r--r--ext/detours/samples/tracelnk/trclnk.cpp (renamed from samples/tracelnk/trclnk.cpp)0
-rw-r--r--ext/detours/samples/tracelnk/trclnk.rc (renamed from samples/tracelnk/trclnk.rc)0
-rw-r--r--ext/detours/samples/tracemem/Makefile (renamed from samples/tracemem/Makefile)0
-rw-r--r--ext/detours/samples/tracemem/trcmem.cpp (renamed from samples/tracemem/trcmem.cpp)0
-rw-r--r--ext/detours/samples/tracemem/trcmem.rc (renamed from samples/tracemem/trcmem.rc)0
-rw-r--r--ext/detours/samples/tracereg/Makefile (renamed from samples/tracereg/Makefile)0
-rw-r--r--ext/detours/samples/tracereg/trcreg.cpp (renamed from samples/tracereg/trcreg.cpp)0
-rw-r--r--ext/detours/samples/tracereg/trcreg.rc (renamed from samples/tracereg/trcreg.rc)0
-rw-r--r--ext/detours/samples/traceser/Makefile (renamed from samples/traceser/Makefile)0
-rw-r--r--ext/detours/samples/traceser/trcser.cpp (renamed from samples/traceser/trcser.cpp)0
-rw-r--r--ext/detours/samples/traceser/trcser.rc (renamed from samples/traceser/trcser.rc)0
-rw-r--r--ext/detours/samples/tracessl/Makefile (renamed from samples/tracessl/Makefile)0
-rw-r--r--ext/detours/samples/tracessl/trcssl.cpp (renamed from samples/tracessl/trcssl.cpp)0
-rw-r--r--ext/detours/samples/tracessl/trcssl.rc (renamed from samples/tracessl/trcssl.rc)0
-rw-r--r--ext/detours/samples/tracetcp/Makefile (renamed from samples/tracetcp/Makefile)0
-rw-r--r--ext/detours/samples/tracetcp/trctcp.cpp (renamed from samples/tracetcp/trctcp.cpp)0
-rw-r--r--ext/detours/samples/tracetcp/trctcp.rc (renamed from samples/tracetcp/trctcp.rc)0
-rw-r--r--ext/detours/samples/tryman/Makefile (renamed from samples/tryman/Makefile)0
-rw-r--r--ext/detours/samples/tryman/managed.cs (renamed from samples/tryman/managed.cs)0
-rw-r--r--ext/detours/samples/tryman/size.cpp (renamed from samples/tryman/size.cpp)0
-rw-r--r--ext/detours/samples/tryman/tryman.cpp (renamed from samples/tryman/tryman.cpp)0
-rw-r--r--ext/detours/samples/tryman/tstman.cpp (renamed from samples/tryman/tstman.cpp)0
-rw-r--r--ext/detours/samples/tryman/tstman.rc (renamed from samples/tryman/tstman.rc)0
-rw-r--r--ext/detours/samples/withdll/Makefile (renamed from samples/withdll/Makefile)0
-rw-r--r--ext/detours/samples/withdll/withdll.cpp (renamed from samples/withdll/withdll.cpp)0
-rw-r--r--ext/detours/src/Makefile (renamed from src/Makefile)0
-rw-r--r--ext/detours/src/creatwth.cpp (renamed from src/creatwth.cpp)0
-rw-r--r--ext/detours/src/detours.cpp (renamed from src/detours.cpp)0
-rw-r--r--ext/detours/src/detours.h (renamed from src/detours.h)0
-rw-r--r--ext/detours/src/detver.h (renamed from src/detver.h)0
-rw-r--r--ext/detours/src/disasm.cpp (renamed from src/disasm.cpp)0
-rw-r--r--ext/detours/src/disolarm.cpp (renamed from src/disolarm.cpp)0
-rw-r--r--ext/detours/src/disolarm64.cpp (renamed from src/disolarm64.cpp)0
-rw-r--r--ext/detours/src/disolia64.cpp (renamed from src/disolia64.cpp)0
-rw-r--r--ext/detours/src/disolx64.cpp (renamed from src/disolx64.cpp)0
-rw-r--r--ext/detours/src/disolx86.cpp (renamed from src/disolx86.cpp)0
-rw-r--r--ext/detours/src/image.cpp (renamed from src/image.cpp)0
-rw-r--r--ext/detours/src/modules.cpp (renamed from src/modules.cpp)0
-rw-r--r--ext/detours/src/uimports.cpp (renamed from src/uimports.cpp)0
-rw-r--r--ext/detours/system.mak (renamed from system.mak)0
-rw-r--r--ext/detours/tests/Makefile (renamed from tests/Makefile)0
-rw-r--r--ext/detours/tests/catch.hpp (renamed from tests/catch.hpp)0
-rw-r--r--ext/detours/tests/corruptor.cpp (renamed from tests/corruptor.cpp)0
-rw-r--r--ext/detours/tests/corruptor.h (renamed from tests/corruptor.h)0
-rw-r--r--ext/detours/tests/main.cpp (renamed from tests/main.cpp)0
-rw-r--r--ext/detours/tests/test_image_api.cpp (renamed from tests/test_image_api.cpp)0
-rw-r--r--ext/detours/tests/test_module_api.cpp (renamed from tests/test_module_api.cpp)0
-rw-r--r--ext/detours/vc/Detours.sln (renamed from vc/Detours.sln)0
-rw-r--r--ext/detours/vc/Detours.vcxproj (renamed from vc/Detours.vcxproj)0
-rw-r--r--ext/detours/vc/Detours.vcxproj.filters (renamed from vc/Detours.vcxproj.filters)0
m---------ext/spirv-headers0
m---------ext/spirv-tools0
-rw-r--r--level_zero-sys/Cargo.toml8
-rw-r--r--level_zero-sys/README4
-rw-r--r--level_zero-sys/build.rs18
-rw-r--r--level_zero-sys/src/lib.rs3
-rw-r--r--level_zero-sys/src/ze_api.rs9948
-rw-r--r--level_zero-sys/src/ze_loader.libbin0 -> 75668 bytes
-rw-r--r--level_zero/Cargo.toml14
-rw-r--r--level_zero/README1
-rw-r--r--level_zero/src/lib.rs4
-rw-r--r--level_zero/src/ze.rs909
-rw-r--r--ptx/Cargo.toml27
-rw-r--r--ptx/build.rs5
-rw-r--r--ptx/lib/zluda_ptx_impl.cl146
-rw-r--r--ptx/lib/zluda_ptx_impl.spvbin0 -> 49500 bytes
-rw-r--r--ptx/src/ast.rs1395
-rw-r--r--ptx/src/lib.rs57
-rw-r--r--ptx/src/ptx.lalrpop2004
-rw-r--r--ptx/src/test/_Z9vectorAddPKfS0_Pfi.ptx10423
-rw-r--r--ptx/src/test/mod.rs49
-rw-r--r--ptx/src/test/operands.ptx33
-rw-r--r--ptx/src/test/spirv_build/bar_sync.ptx10
-rw-r--r--ptx/src/test/spirv_build/global_extern_array.ptx5
-rw-r--r--ptx/src/test/spirv_build/param_func_array_0.ptx10
-rw-r--r--ptx/src/test/spirv_fail/const_ptr.ptx5
-rw-r--r--ptx/src/test/spirv_fail/global_ptr.ptx5
-rw-r--r--ptx/src/test/spirv_fail/local_ptr.txt12
-rw-r--r--ptx/src/test/spirv_fail/param_entry_array_0.ptx10
-rw-r--r--ptx/src/test/spirv_fail/param_vector.ptx10
-rw-r--r--ptx/src/test/spirv_fail/shared_ptr.ptx5
-rw-r--r--ptx/src/test/spirv_fail/shared_ptr2.ptx13
-rw-r--r--ptx/src/test/spirv_run/add.ptx22
-rw-r--r--ptx/src/test/spirv_run/add.spvtxt47
-rw-r--r--ptx/src/test/spirv_run/and.ptx23
-rw-r--r--ptx/src/test/spirv_run/and.spvtxt58
-rw-r--r--ptx/src/test/spirv_run/assertfail.ptx79
-rw-r--r--ptx/src/test/spirv_run/assertfail.spvtxt105
-rw-r--r--ptx/src/test/spirv_run/atom_add.ptx28
-rw-r--r--ptx/src/test/spirv_run/atom_add.spvtxt76
-rw-r--r--ptx/src/test/spirv_run/atom_cas.ptx24
-rw-r--r--ptx/src/test/spirv_run/atom_cas.spvtxt69
-rw-r--r--ptx/src/test/spirv_run/atom_inc.ptx26
-rw-r--r--ptx/src/test/spirv_run/atom_inc.spvtxt81
-rw-r--r--ptx/src/test/spirv_run/b64tof64.ptx25
-rw-r--r--ptx/src/test/spirv_run/b64tof64.spvtxt50
-rw-r--r--ptx/src/test/spirv_run/bfe.ptx23
-rw-r--r--ptx/src/test/spirv_run/bfe.spvtxt70
-rw-r--r--ptx/src/test/spirv_run/block.ptx26
-rw-r--r--ptx/src/test/spirv_run/block.spvtxt52
-rw-r--r--ptx/src/test/spirv_run/bra.ptx28
-rw-r--r--ptx/src/test/spirv_run/bra.spvtxt57
-rw-r--r--ptx/src/test/spirv_run/brev.ptx21
-rw-r--r--ptx/src/test/spirv_run/brev.spvtxt47
-rw-r--r--ptx/src/test/spirv_run/call.ptx38
-rw-r--r--ptx/src/test/spirv_run/call.spvtxt67
-rw-r--r--ptx/src/test/spirv_run/clz.ptx21
-rw-r--r--ptx/src/test/spirv_run/clz.spvtxt47
-rw-r--r--ptx/src/test/spirv_run/constant_f32.ptx21
-rw-r--r--ptx/src/test/spirv_run/constant_f32.spvtxt48
-rw-r--r--ptx/src/test/spirv_run/constant_negative.ptx21
-rw-r--r--ptx/src/test/spirv_run/constant_negative.spvtxt48
-rw-r--r--ptx/src/test/spirv_run/cos.ptx21
-rw-r--r--ptx/src/test/spirv_run/cos.spvtxt47
-rw-r--r--ptx/src/test/spirv_run/cvt_rni.ptx25
-rw-r--r--ptx/src/test/spirv_run/cvt_rni.spvtxt63
-rw-r--r--ptx/src/test/spirv_run/cvt_sat_s_u.ptx24
-rw-r--r--ptx/src/test/spirv_run/cvt_sat_s_u.spvtxt52
-rw-r--r--ptx/src/test/spirv_run/cvta.ptx23
-rw-r--r--ptx/src/test/spirv_run/cvta.spvtxt65
-rw-r--r--ptx/src/test/spirv_run/div_approx.ptx23
-rw-r--r--ptx/src/test/spirv_run/div_approx.spvtxt56
-rw-r--r--ptx/src/test/spirv_run/ex2.ptx21
-rw-r--r--ptx/src/test/spirv_run/ex2.spvtxt47
-rw-r--r--ptx/src/test/spirv_run/extern_shared.ptx24
-rw-r--r--ptx/src/test/spirv_run/extern_shared.spvtxt66
-rw-r--r--ptx/src/test/spirv_run/extern_shared_call.ptx35
-rw-r--r--ptx/src/test/spirv_run/extern_shared_call.spvtxt93
-rw-r--r--ptx/src/test/spirv_run/fma.ptx25
-rw-r--r--ptx/src/test/spirv_run/fma.spvtxt63
-rw-r--r--ptx/src/test/spirv_run/global_array.ptx22
-rw-r--r--ptx/src/test/spirv_run/global_array.spvtxt53
-rw-r--r--ptx/src/test/spirv_run/implicit_param.ptx24
-rw-r--r--ptx/src/test/spirv_run/implicit_param.spvtxt53
-rw-r--r--ptx/src/test/spirv_run/ld_st.ptx20
-rw-r--r--ptx/src/test/spirv_run/ld_st.spvtxt42
-rw-r--r--ptx/src/test/spirv_run/ld_st_implicit.ptx20
-rw-r--r--ptx/src/test/spirv_run/ld_st_implicit.spvtxt49
-rw-r--r--ptx/src/test/spirv_run/ld_st_offset.ptx23
-rw-r--r--ptx/src/test/spirv_run/ld_st_offset.spvtxt57
-rw-r--r--ptx/src/test/spirv_run/lg2.ptx21
-rw-r--r--ptx/src/test/spirv_run/lg2.spvtxt47
-rw-r--r--ptx/src/test/spirv_run/local_align.ptx21
-rw-r--r--ptx/src/test/spirv_run/local_align.spvtxt49
-rw-r--r--ptx/src/test/spirv_run/mad_s32.ptx28
-rw-r--r--ptx/src/test/spirv_run/mad_s32.spvtxt77
-rw-r--r--ptx/src/test/spirv_run/max.ptx23
-rw-r--r--ptx/src/test/spirv_run/max.spvtxt55
-rw-r--r--ptx/src/test/spirv_run/min.ptx23
-rw-r--r--ptx/src/test/spirv_run/min.spvtxt55
-rw-r--r--ptx/src/test/spirv_run/mod.rs523
-rw-r--r--ptx/src/test/spirv_run/mov.ptx22
-rw-r--r--ptx/src/test/spirv_run/mov.spvtxt46
-rw-r--r--ptx/src/test/spirv_run/mov_address.ptx15
-rw-r--r--ptx/src/test/spirv_run/mov_address.spvtxt33
-rw-r--r--ptx/src/test/spirv_run/mul_ftz.ptx23
-rw-r--r--ptx/src/test/spirv_run/mul_ftz.spvtxt55
-rw-r--r--ptx/src/test/spirv_run/mul_hi.ptx22
-rw-r--r--ptx/src/test/spirv_run/mul_hi.spvtxt47
-rw-r--r--ptx/src/test/spirv_run/mul_lo.ptx22
-rw-r--r--ptx/src/test/spirv_run/mul_lo.spvtxt47
-rw-r--r--ptx/src/test/spirv_run/mul_non_ftz.ptx23
-rw-r--r--ptx/src/test/spirv_run/mul_non_ftz.spvtxt55
-rw-r--r--ptx/src/test/spirv_run/mul_wide.ptx24
-rw-r--r--ptx/src/test/spirv_run/mul_wide.spvtxt64
-rw-r--r--ptx/src/test/spirv_run/neg.ptx21
-rw-r--r--ptx/src/test/spirv_run/neg.spvtxt47
-rw-r--r--ptx/src/test/spirv_run/not.ptx22
-rw-r--r--ptx/src/test/spirv_run/not.spvtxt48
-rw-r--r--ptx/src/test/spirv_run/ntid.ptx23
-rw-r--r--ptx/src/test/spirv_run/ntid.spvtxt59
-rw-r--r--ptx/src/test/spirv_run/or.ptx23
-rw-r--r--ptx/src/test/spirv_run/or.spvtxt56
-rw-r--r--ptx/src/test/spirv_run/popc.ptx21
-rw-r--r--ptx/src/test/spirv_run/popc.spvtxt47
-rw-r--r--ptx/src/test/spirv_run/pred_not.ptx28
-rw-r--r--ptx/src/test/spirv_run/pred_not.spvtxt78
-rw-r--r--ptx/src/test/spirv_run/rcp.ptx21
-rw-r--r--ptx/src/test/spirv_run/rcp.spvtxt49
-rw-r--r--ptx/src/test/spirv_run/reg_local.ptx23
-rw-r--r--ptx/src/test/spirv_run/reg_local.spvtxt69
-rw-r--r--ptx/src/test/spirv_run/rem.ptx23
-rw-r--r--ptx/src/test/spirv_run/rem.spvtxt55
-rw-r--r--ptx/src/test/spirv_run/rsqrt.ptx21
-rw-r--r--ptx/src/test/spirv_run/rsqrt.spvtxt47
-rw-r--r--ptx/src/test/spirv_run/selp.ptx23
-rw-r--r--ptx/src/test/spirv_run/selp.spvtxt57
-rw-r--r--ptx/src/test/spirv_run/selp_true.ptx23
-rw-r--r--ptx/src/test/spirv_run/selp_true.spvtxt57
-rw-r--r--ptx/src/test/spirv_run/setp.ptx27
-rw-r--r--ptx/src/test/spirv_run/setp.spvtxt73
-rw-r--r--ptx/src/test/spirv_run/shared_ptr_32.ptx29
-rw-r--r--ptx/src/test/spirv_run/shared_ptr_32.spvtxt66
-rw-r--r--ptx/src/test/spirv_run/shared_ptr_take_address.ptx27
-rw-r--r--ptx/src/test/spirv_run/shared_ptr_take_address.spvtxt68
-rw-r--r--ptx/src/test/spirv_run/shared_variable.ptx26
-rw-r--r--ptx/src/test/spirv_run/shared_variable.spvtxt57
-rw-r--r--ptx/src/test/spirv_run/shl.ptx22
-rw-r--r--ptx/src/test/spirv_run/shl.spvtxt51
-rw-r--r--ptx/src/test/spirv_run/shl_link_hack.ptx30
-rw-r--r--ptx/src/test/spirv_run/shl_link_hack.spvtxt65
-rw-r--r--ptx/src/test/spirv_run/shr.ptx21
-rw-r--r--ptx/src/test/spirv_run/shr.spvtxt48
-rw-r--r--ptx/src/test/spirv_run/sin.ptx21
-rw-r--r--ptx/src/test/spirv_run/sin.spvtxt47
-rw-r--r--ptx/src/test/spirv_run/sqrt.ptx21
-rw-r--r--ptx/src/test/spirv_run/sqrt.spvtxt47
-rw-r--r--ptx/src/test/spirv_run/stateful_ld_st_ntid.ptx31
-rw-r--r--ptx/src/test/spirv_run/stateful_ld_st_ntid.spvtxt91
-rw-r--r--ptx/src/test/spirv_run/stateful_ld_st_ntid_chain.ptx35
-rw-r--r--ptx/src/test/spirv_run/stateful_ld_st_ntid_chain.spvtxt95
-rw-r--r--ptx/src/test/spirv_run/stateful_ld_st_ntid_sub.ptx35
-rw-r--r--ptx/src/test/spirv_run/stateful_ld_st_ntid_sub.spvtxt107
-rw-r--r--ptx/src/test/spirv_run/stateful_ld_st_simple.ptx25
-rw-r--r--ptx/src/test/spirv_run/stateful_ld_st_simple.spvtxt65
-rw-r--r--ptx/src/test/spirv_run/sub.ptx22
-rw-r--r--ptx/src/test/spirv_run/sub.spvtxt47
-rw-r--r--ptx/src/test/spirv_run/vector.ptx45
-rw-r--r--ptx/src/test/spirv_run/vector.spvtxt99
-rw-r--r--ptx/src/test/spirv_run/vector_extract.ptx27
-rw-r--r--ptx/src/test/spirv_run/vector_extract.spvtxt125
-rw-r--r--ptx/src/test/spirv_run/xor.ptx23
-rw-r--r--ptx/src/test/spirv_run/xor.spvtxt55
-rw-r--r--ptx/src/test/vectorAdd_11.ptx55
-rw-r--r--ptx/src/test/vectorAdd_kernel64.ptx592
-rw-r--r--ptx/src/translate.rs7647
-rw-r--r--spirv_tools-sys/Cargo.toml10
-rw-r--r--spirv_tools-sys/README1
-rw-r--r--spirv_tools-sys/build.rs28
-rw-r--r--spirv_tools-sys/src/lib.rs3
-rw-r--r--spirv_tools-sys/src/spirv_tools.rs972
-rw-r--r--zluda/Cargo.toml21
-rw-r--r--zluda/README3
-rw-r--r--zluda/build.rs27
-rw-r--r--zluda/src/cuda.rs4496
-rw-r--r--zluda/src/cuda_impl/mod.rs1
-rw-r--r--zluda/src/cuda_impl/rt.rs2
-rw-r--r--zluda/src/impl/context.rs359
-rw-r--r--zluda/src/impl/device.rs407
-rw-r--r--zluda/src/impl/export_table.rs372
-rw-r--r--zluda/src/impl/function.rs112
-rw-r--r--zluda/src/impl/memory.rs100
-rw-r--r--zluda/src/impl/mod.rs351
-rw-r--r--zluda/src/impl/module.rs188
-rw-r--r--zluda/src/impl/stream.rs242
-rw-r--r--zluda/src/impl/test.rs157
-rw-r--r--zluda/src/lib.rs16
-rw-r--r--zluda_inject/Cargo.toml16
-rw-r--r--zluda_inject/src/bin.rs106
-rw-r--r--zluda_inject/src/main.rs5
-rw-r--r--zluda_inject/src/win.rs148
-rw-r--r--zluda_redirect/Cargo.toml14
-rw-r--r--zluda_redirect/src/lib.rs105
389 files changed, 48643 insertions, 80 deletions
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
new file mode 100644
index 0000000..734052f
--- /dev/null
+++ b/.github/workflows/rust.yml
@@ -0,0 +1,54 @@
+name: Rust
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+env:
+ CARGO_TERM_COLOR: always
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ submodules: true
+ - uses: actions/cache@v2
+ with:
+ path: |
+ ~/.cargo/registry
+ ~/.cargo/git
+ target
+ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
+ - name: Install intel compute runtime
+ run: |
+ mkdir neo
+ cd neo
+ wget https://github.com/intel/compute-runtime/releases/download/20.51.18762/intel-gmmlib_20.3.2_amd64.deb
+ wget https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.5884/intel-igc-core_1.0.5884_amd64.deb
+ wget https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.5884/intel-igc-opencl_1.0.5884_amd64.deb
+ wget https://github.com/intel/compute-runtime/releases/download/20.51.18762/intel-opencl_20.51.18762_amd64.deb
+ wget https://github.com/intel/compute-runtime/releases/download/20.51.18762/intel-ocloc_20.51.18762_amd64.deb
+ wget https://github.com/intel/compute-runtime/releases/download/20.51.18762/intel-level-zero-gpu_1.0.18762_amd64.deb
+
+ wget https://github.com/intel/compute-runtime/releases/download/20.51.18762/ww51.sum
+ sha256sum -c ww51.sum
+
+ wget https://github.com/oneapi-src/level-zero/releases/download/v1.0.22/level-zero-devel_1.0.22+u18.04_amd64.deb
+ wget https://github.com/oneapi-src/level-zero/releases/download/v1.0.22/level-zero_1.0.22+u18.04_amd64.deb
+ wget https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.5884/intel-igc-opencl-devel_1.0.5884_amd64.deb
+
+ sudo dpkg -i *.deb
+
+ sudo apt update
+ sudo apt install ocl-icd-opencl-dev
+ - name: Build
+ run: cargo build --verbose
+ # TODO(take-cheeze): Support testing
+ # - name: Run tests
+ # run: cargo test --verbose
diff --git a/.gitignore b/.gitignore
index b5a68d4..76550e8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,41 +1,5 @@
-# C extensions
-*.so
-
-# Unit test / coverage reports
-.coverage
-.tox
-nosetests.xml
-
-# Translations
-*.mo
-
-# Mr Developer
-.mr.developer.cfg
-.project
-.pydevproject
-
-# vim
-*~
-*.swp
-
-# Visual Studio build
-*.ipch
-.vs/
-output/
-include/
-*.exp
-*.pdb
-*.lib
-*.dll
-*.exe
-obj.*
-*.ipdb
-*.iobj
-*.tlog
-*.log
-*.obj
-*.user
-*.recipe
-/bin.*
-*.vcxproj.FileListAbsolute.txt
-*.vcxprojAssemblyReference.cache
+target/
+Cargo.lock
+
+.vscode/
+.idea/ \ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..9796b04
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,7 @@
+[submodule "ext/spirv-tools"]
+ path = ext/spirv-tools
+ url = https://github.com/KhronosGroup/SPIRV-Tools
+ branch = master
+[submodule "ext/spirv-headers"]
+ path = ext/spirv-headers
+ url = https://github.com/KhronosGroup/SPIRV-Headers
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..d50aad0
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,15 @@
+[workspace]
+
+members = [
+ "level_zero-sys",
+ "level_zero",
+ "spirv_tools-sys",
+ "zluda",
+ #"zluda_inject",
+ #"zluda_redirect",
+ "ptx",
+]
+
+[patch.crates-io]
+rspirv = { git = 'https://github.com/vosen/rspirv', rev = '40f5aa4dedb0d9f1ec24bdd8b6019e01996d1d74' }
+spirv_headers = { git = 'https://github.com/vosen/rspirv', rev = '40f5aa4dedb0d9f1ec24bdd8b6019e01996d1d74' } \ No newline at end of file
diff --git a/GeekBench_5_2_3.svg b/GeekBench_5_2_3.svg
new file mode 100644
index 0000000..1bc47be
--- /dev/null
+++ b/GeekBench_5_2_3.svg
@@ -0,0 +1 @@
+<svg version="1.1" viewBox="0.0 0.0 770.0 370.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" width="770" height="370" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M0 0L770.0 0L770.0 370.0L0 370.0L0 0Z" fill-rule="nonzero"/><path stroke="#333333" stroke-width="1.0" stroke-linecap="butt" d="M73.5 331.5L751.5 331.5" fill-rule="nonzero"/><path stroke="#cccccc" stroke-width="1.0" stroke-linecap="butt" d="M73.5 250.5L751.5 250.5" fill-rule="nonzero"/><path stroke="#cccccc" stroke-width="1.0" stroke-linecap="butt" d="M73.5 169.5L751.5 169.5" fill-rule="nonzero"/><path stroke="#cccccc" stroke-width="1.0" stroke-linecap="butt" d="M73.5 88.5L751.5 88.5" fill-rule="nonzero"/><clipPath id="id_0"><path d="M73.5 88.166664L751.5 88.166664L751.5 331.5L73.5 331.5L73.5 88.166664Z" clip-rule="nonzero"/></clipPath><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" stroke-opacity="0.0" clip-path="url(#id_0)" d="M145.0 332.0L112.0 332.0L112.0 168.0C112.0 166.89543 112.89543 166.0 114.0 166.0L143.0 166.0C144.10457 166.0 145.0 166.89543 145.0 168.0Z" fill-rule="nonzero"/><path fill="#4285f4" clip-path="url(#id_0)" d="M145.0 332.0L112.0 332.0L112.0 168.0C112.0 166.89543 112.89543 166.0 114.0 166.0L143.0 166.0C144.10457 166.0 145.0 166.89543 145.0 168.0Z" fill-rule="nonzero"/><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" stroke-opacity="0.0" clip-path="url(#id_0)" d="M251.0 332.0L218.0 332.0L218.0 210.0C218.0 208.89543 218.89543 208.0 220.0 208.0L249.0 208.0C250.10457 208.0 251.0 208.89543 251.0 210.0Z" fill-rule="nonzero"/><path fill="#4285f4" clip-path="url(#id_0)" d="M251.0 332.0L218.0 332.0L218.0 210.0C218.0 208.89543 218.89543 208.0 220.0 208.0L249.0 208.0C250.10457 208.0 251.0 208.89543 251.0 210.0Z" fill-rule="nonzero"/><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" stroke-opacity="0.0" clip-path="url(#id_0)" d="M358.0 332.0L325.0 332.0L325.0 98.0C325.0 96.89543 325.89542 96.0 327.0 96.0L356.0 96.0C357.10458 96.0 358.0 96.89543 358.0 98.0Z" fill-rule="nonzero"/><path fill="#4285f4" clip-path="url(#id_0)" d="M358.0 332.0L325.0 332.0L325.0 98.0C325.0 96.89543 325.89542 96.0 327.0 96.0L356.0 96.0C357.10458 96.0 358.0 96.89543 358.0 98.0Z" fill-rule="nonzero"/><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" stroke-opacity="0.0" clip-path="url(#id_0)" d="M465.0 332.0L432.0 332.0L432.0 158.0C432.0 156.89543 432.89542 156.0 434.0 156.0L463.0 156.0C464.10458 156.0 465.0 156.89543 465.0 158.0Z" fill-rule="nonzero"/><path fill="#4285f4" clip-path="url(#id_0)" d="M465.0 332.0L432.0 332.0L432.0 158.0C432.0 156.89543 432.89542 156.0 434.0 156.0L463.0 156.0C464.10458 156.0 465.0 156.89543 465.0 158.0Z" fill-rule="nonzero"/><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" stroke-opacity="0.0" clip-path="url(#id_0)" d="M572.0 332.0L539.0 332.0L539.0 142.0C539.0 140.89543 539.89545 140.0 541.0 140.0L570.0 140.0C571.10455 140.0 572.0 140.89543 572.0 142.0Z" fill-rule="nonzero"/><path fill="#4285f4" clip-path="url(#id_0)" d="M572.0 332.0L539.0 332.0L539.0 142.0C539.0 140.89543 539.89545 140.0 541.0 140.0L570.0 140.0C571.10455 140.0 572.0 140.89543 572.0 142.0Z" fill-rule="nonzero"/><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" stroke-opacity="0.0" clip-path="url(#id_0)" d="M678.0 332.0L645.0 332.0L645.0 189.0C645.0 187.89543 645.89545 187.0 647.0 187.0L676.0 187.0C677.10455 187.0 678.0 187.89543 678.0 189.0Z" fill-rule="nonzero"/><path fill="#4285f4" clip-path="url(#id_0)" d="M678.0 332.0L645.0 332.0L645.0 189.0C645.0 187.89543 645.89545 187.0 647.0 187.0L676.0 187.0C677.10455 187.0 678.0 187.89543 678.0 189.0Z" fill-rule="nonzero"/><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" stroke-opacity="0.0" clip-path="url(#id_0)" d="M180.0 332.0L147.0 332.0L147.0 171.0C147.0 169.89543 147.89543 169.0 149.0 169.0L178.0 169.0C179.10457 169.0 180.0 169.89543 180.0 171.0Z" fill-rule="nonzero"/><path fill="#ea4335" clip-path="url(#id_0)" d="M180.0 332.0L147.0 332.0L147.0 171.0C147.0 169.89543 147.89543 169.0 149.0 169.0L178.0 169.0C179.10457 169.0 180.0 169.89543 180.0 171.0Z" fill-rule="nonzero"/><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" stroke-opacity="0.0" clip-path="url(#id_0)" d="M286.0 332.0L253.0 332.0L253.0 171.0C253.0 169.89543 253.89543 169.0 255.0 169.0L284.0 169.0C285.10458 169.0 286.0 169.89543 286.0 171.0Z" fill-rule="nonzero"/><path fill="#ea4335" clip-path="url(#id_0)" d="M286.0 332.0L253.0 332.0L253.0 171.0C253.0 169.89543 253.89543 169.0 255.0 169.0L284.0 169.0C285.10458 169.0 286.0 169.89543 286.0 171.0Z" fill-rule="nonzero"/><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" stroke-opacity="0.0" clip-path="url(#id_0)" d="M393.0 332.0L360.0 332.0L360.0 171.0C360.0 169.89543 360.89542 169.0 362.0 169.0L391.0 169.0C392.10458 169.0 393.0 169.89543 393.0 171.0Z" fill-rule="nonzero"/><path fill="#ea4335" clip-path="url(#id_0)" d="M393.0 332.0L360.0 332.0L360.0 171.0C360.0 169.89543 360.89542 169.0 362.0 169.0L391.0 169.0C392.10458 169.0 393.0 169.89543 393.0 171.0Z" fill-rule="nonzero"/><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" stroke-opacity="0.0" clip-path="url(#id_0)" d="M500.0 332.0L467.0 332.0L467.0 171.0C467.0 169.89543 467.89542 169.0 469.0 169.0L498.0 169.0C499.10458 169.0 500.0 169.89543 500.0 171.0Z" fill-rule="nonzero"/><path fill="#ea4335" clip-path="url(#id_0)" d="M500.0 332.0L467.0 332.0L467.0 171.0C467.0 169.89543 467.89542 169.0 469.0 169.0L498.0 169.0C499.10458 169.0 500.0 169.89543 500.0 171.0Z" fill-rule="nonzero"/><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" stroke-opacity="0.0" clip-path="url(#id_0)" d="M607.0 332.0L574.0 332.0L574.0 171.0C574.0 169.89543 574.89545 169.0 576.0 169.0L605.0 169.0C606.10455 169.0 607.0 169.89543 607.0 171.0Z" fill-rule="nonzero"/><path fill="#ea4335" clip-path="url(#id_0)" d="M607.0 332.0L574.0 332.0L574.0 171.0C574.0 169.89543 574.89545 169.0 576.0 169.0L605.0 169.0C606.10455 169.0 607.0 169.89543 607.0 171.0Z" fill-rule="nonzero"/><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" stroke-opacity="0.0" clip-path="url(#id_0)" d="M713.0 332.0L680.0 332.0L680.0 171.0C680.0 169.89543 680.89545 169.0 682.0 169.0L711.0 169.0C712.10455 169.0 713.0 169.89543 713.0 171.0Z" fill-rule="nonzero"/><path fill="#ea4335" clip-path="url(#id_0)" d="M713.0 332.0L680.0 332.0L680.0 171.0C680.0 169.89543 680.89545 169.0 682.0 169.0L711.0 169.0C712.10455 169.0 713.0 169.89543 713.0 171.0Z" fill-rule="nonzero"/><path fill="#000000" d="M33.0 331.26562Q33.0 329.73438 33.3125 328.8125Q33.625 327.875 34.234375 327.375Q34.859375 326.875 35.796875 326.875Q36.484375 326.875 37.0 327.15625Q37.53125 327.4375 37.875 327.96875Q38.21875 328.48438 38.40625 329.23438Q38.59375 329.98438 38.59375 331.26562Q38.59375 332.78125 38.28125 333.70312Q37.984375 334.625 37.359375 335.14062Q36.75 335.64062 35.796875 335.64062Q34.5625 335.64062 33.84375 334.75Q33.0 333.6875 33.0 331.26562ZM34.078125 331.26562Q34.078125 333.375 34.578125 334.07812Q35.078125 334.78125 35.796875 334.78125Q36.53125 334.78125 37.015625 334.07812Q37.515625 333.375 37.515625 331.26562Q37.515625 329.14062 37.015625 328.45312Q36.53125 327.75 35.78125 327.75Q35.0625 327.75 34.625 328.35938Q34.078125 329.14062 34.078125 331.26562ZM40.59375 335.5L40.59375 334.29688L41.796875 334.29688L41.796875 335.5L40.59375 335.5ZM43.0 331.26562Q43.0 329.73438 43.3125 328.8125Q43.625 327.875 44.234375 327.375Q44.859375 326.875 45.796875 326.875Q46.484375 326.875 47.0 327.15625Q47.53125 327.4375 47.875 327.96875Q48.21875 328.48438 48.40625 329.23438Q48.59375 329.98438 48.59375 331.26562Q48.59375 332.78125 48.28125 333.70312Q47.984375 334.625 47.359375 335.14062Q46.75 335.64062 45.796875 335.64062Q44.5625 335.64062 43.84375 334.75Q43.0 333.6875 43.0 331.26562ZM44.078125 331.26562Q44.078125 333.375 44.578125 334.07812Q45.078125 334.78125 45.796875 334.78125Q46.53125 334.78125 47.015625 334.07812Q47.515625 333.375 47.515625 331.26562Q47.515625 329.14062 47.015625 328.45312Q46.53125 327.75 45.78125 327.75Q45.0625 327.75 44.625 328.35938Q44.078125 329.14062 44.078125 331.26562ZM50.0 331.26562Q50.0 329.73438 50.3125 328.8125Q50.625 327.875 51.234375 327.375Q51.859375 326.875 52.796875 326.875Q53.484375 326.875 54.0 327.15625Q54.53125 327.4375 54.875 327.96875Q55.21875 328.48438 55.40625 329.23438Q55.59375 329.98438 55.59375 331.26562Q55.59375 332.78125 55.28125 333.70312Q54.984375 334.625 54.359375 335.14062Q53.75 335.64062 52.796875 335.64062Q51.5625 335.64062 50.84375 334.75Q50.0 333.6875 50.0 331.26562ZM51.078125 331.26562Q51.078125 333.375 51.578125 334.07812Q52.078125 334.78125 52.796875 334.78125Q53.53125 334.78125 54.015625 334.07812Q54.515625 333.375 54.515625 331.26562Q54.515625 329.14062 54.015625 328.45312Q53.53125 327.75 52.78125 327.75Q52.0625 327.75 51.625 328.35938Q51.078125 329.14062 51.078125 331.26562ZM57.203125 328.96875Q57.203125 328.04688 57.65625 327.40625Q58.125 326.76562 59.0 326.76562Q59.8125 326.76562 60.34375 327.34375Q60.875 327.92188 60.875 329.03125Q60.875 330.125 60.328125 330.71875Q59.796875 331.29688 59.015625 331.29688Q58.234375 331.29688 57.71875 330.71875Q57.203125 330.14062 57.203125 328.96875ZM59.03125 327.48438Q58.640625 327.48438 58.375 327.82812Q58.125 328.17188 58.125 329.07812Q58.125 329.90625 58.375 330.25Q58.640625 330.57812 59.03125 330.57812Q59.4375 330.57812 59.6875 330.23438Q59.953125 329.89062 59.953125 329.0Q59.953125 328.15625 59.6875 327.82812Q59.421875 327.48438 59.03125 327.48438ZM59.03125 335.8125L63.734375 326.76562L64.59375 326.76562L59.90625 335.8125L59.03125 335.8125ZM62.75 333.48438Q62.75 332.5625 63.203125 331.92188Q63.671875 331.28125 64.5625 331.28125Q65.375 331.28125 65.90625 331.85938Q66.4375 332.42188 66.4375 333.54688Q66.4375 334.64062 65.890625 335.23438Q65.359375 335.8125 64.5625 335.8125Q63.796875 335.8125 63.265625 335.23438Q62.75 334.65625 62.75 333.48438ZM64.59375 332.0Q64.1875 332.0 63.921875 332.34375Q63.671875 332.6875 63.671875 333.59375Q63.671875 334.40625 63.9375 334.75Q64.203125 335.09375 64.59375 335.09375Q64.984375 335.09375 65.25 334.75Q65.515625 334.40625 65.515625 333.5Q65.515625 332.67188 65.25 332.34375Q64.984375 332.0 64.59375 332.0Z" fill-rule="nonzero"/><path fill="#000000" d="M26.0 252.13889L27.109375 252.04514Q27.234375 252.85764 27.671875 253.26389Q28.125 253.67014 28.765625 253.67014Q29.515625 253.67014 30.046875 253.09201Q30.578125 252.51389 30.578125 251.57639Q30.578125 250.67014 30.0625 250.15451Q29.5625 249.62326 28.734375 249.62326Q28.234375 249.62326 27.8125 249.85764Q27.40625 250.09201 27.171875 250.45139L26.1875 250.32639L27.015625 245.92014L31.296875 245.92014L31.296875 246.92014L27.859375 246.92014L27.40625 249.23264Q28.171875 248.68576 29.015625 248.68576Q30.140625 248.68576 30.90625 249.46701Q31.6875 250.24826 31.6875 251.48264Q31.6875 252.63889 31.015625 253.49826Q30.1875 254.52951 28.765625 254.52951Q27.59375 254.52951 26.84375 253.87326Q26.109375 253.21701 26.0 252.13889ZM33.0 250.15451Q33.0 248.62326 33.3125 247.70139Q33.625 246.76389 34.234375 246.26389Q34.859375 245.76389 35.796875 245.76389Q36.484375 245.76389 37.0 246.04514Q37.53125 246.32639 37.875 246.85764Q38.21875 247.37326 38.40625 248.12326Q38.59375 248.87326 38.59375 250.15451Q38.59375 251.67014 38.28125 252.59201Q37.984375 253.51389 37.359375 254.02951Q36.75 254.52951 35.796875 254.52951Q34.5625 254.52951 33.84375 253.63889Q33.0 252.57639 33.0 250.15451ZM34.078125 250.15451Q34.078125 252.26389 34.578125 252.96701Q35.078125 253.67014 35.796875 253.67014Q36.53125 253.67014 37.015625 252.96701Q37.515625 252.26389 37.515625 250.15451Q37.515625 248.02951 37.015625 247.34201Q36.53125 246.63889 35.78125 246.63889Q35.0625 246.63889 34.625 247.24826Q34.078125 248.02951 34.078125 250.15451ZM40.59375 254.38889L40.59375 253.18576L41.796875 253.18576L41.796875 254.38889L40.59375 254.38889ZM43.0 250.15451Q43.0 248.62326 43.3125 247.70139Q43.625 246.76389 44.234375 246.26389Q44.859375 245.76389 45.796875 245.76389Q46.484375 245.76389 47.0 246.04514Q47.53125 246.32639 47.875 246.85764Q48.21875 247.37326 48.40625 248.12326Q48.59375 248.87326 48.59375 250.15451Q48.59375 251.67014 48.28125 252.59201Q47.984375 253.51389 47.359375 254.02951Q46.75 254.52951 45.796875 254.52951Q44.5625 254.52951 43.84375 253.63889Q43.0 252.57639 43.0 250.15451ZM44.078125 250.15451Q44.078125 252.26389 44.578125 252.96701Q45.078125 253.67014 45.796875 253.67014Q46.53125 253.67014 47.015625 252.96701Q47.515625 252.26389 47.515625 250.15451Q47.515625 248.02951 47.015625 247.34201Q46.53125 246.63889 45.78125 246.63889Q45.0625 246.63889 44.625 247.24826Q44.078125 248.02951 44.078125 250.15451ZM50.0 250.15451Q50.0 248.62326 50.3125 247.70139Q50.625 246.76389 51.234375 246.26389Q51.859375 245.76389 52.796875 245.76389Q53.484375 245.76389 54.0 246.04514Q54.53125 246.32639 54.875 246.85764Q55.21875 247.37326 55.40625 248.12326Q55.59375 248.87326 55.59375 250.15451Q55.59375 251.67014 55.28125 252.59201Q54.984375 253.51389 54.359375 254.02951Q53.75 254.52951 52.796875 254.52951Q51.5625 254.52951 50.84375 253.63889Q50.0 252.57639 50.0 250.15451ZM51.078125 250.15451Q51.078125 252.26389 51.578125 252.96701Q52.078125 253.67014 52.796875 253.67014Q53.53125 253.67014 54.015625 252.96701Q54.515625 252.26389 54.515625 250.15451Q54.515625 248.02951 54.015625 247.34201Q53.53125 246.63889 52.78125 246.63889Q52.0625 246.63889 51.625 247.24826Q51.078125 248.02951 51.078125 250.15451ZM57.203125 247.85764Q57.203125 246.93576 57.65625 246.29514Q58.125 245.65451 59.0 245.65451Q59.8125 245.65451 60.34375 246.23264Q60.875 246.81076 60.875 247.92014Q60.875 249.01389 60.328125 249.60764Q59.796875 250.18576 59.015625 250.18576Q58.234375 250.18576 57.71875 249.60764Q57.203125 249.02951 57.203125 247.85764ZM59.03125 246.37326Q58.640625 246.37326 58.375 246.71701Q58.125 247.06076 58.125 247.96701Q58.125 248.79514 58.375 249.13889Q58.640625 249.46701 59.03125 249.46701Q59.4375 249.46701 59.6875 249.12326Q59.953125 248.77951 59.953125 247.88889Q59.953125 247.04514 59.6875 246.71701Q59.421875 246.37326 59.03125 246.37326ZM59.03125 254.70139L63.734375 245.65451L64.59375 245.65451L59.90625 254.70139L59.03125 254.70139ZM62.75 252.37326Q62.75 251.45139 63.203125 250.81076Q63.671875 250.17014 64.5625 250.17014Q65.375 250.17014 65.90625 250.74826Q66.4375 251.31076 66.4375 252.43576Q66.4375 253.52951 65.890625 254.12326Q65.359375 254.70139 64.5625 254.70139Q63.796875 254.70139 63.265625 254.12326Q62.75 253.54514 62.75 252.37326ZM64.59375 250.88889Q64.1875 250.88889 63.921875 251.23264Q63.671875 251.57639 63.671875 252.48264Q63.671875 253.29514 63.9375 253.63889Q64.203125 253.98264 64.59375 253.98264Q64.984375 253.98264 65.25 253.63889Q65.515625 253.29514 65.515625 252.38889Q65.515625 251.56076 65.25 251.23264Q64.984375 250.88889 64.59375 250.88889Z" fill-rule="nonzero"/><path fill="#000000" d="M22.96875 173.27777L21.921875 173.27777L21.921875 166.55902Q21.53125 166.9184 20.90625 167.2934Q20.296875 167.65277 19.8125 167.82465L19.8125 166.80902Q20.6875 166.38715 21.34375 165.80902Q22.015625 165.21527 22.296875 164.65277L22.96875 164.65277L22.96875 173.27777ZM26.0 169.0434Q26.0 167.51215 26.3125 166.59027Q26.625 165.65277 27.234375 165.15277Q27.859375 164.65277 28.796875 164.65277Q29.484375 164.65277 30.0 164.93402Q30.53125 165.21527 30.875 165.74652Q31.21875 166.26215 31.40625 167.01215Q31.59375 167.76215 31.59375 169.0434Q31.59375 170.55902 31.28125 171.4809Q30.984375 172.40277 30.359375 172.9184Q29.75 173.4184 28.796875 173.4184Q27.5625 173.4184 26.84375 172.52777Q26.0 171.46527 26.0 169.0434ZM27.078125 169.0434Q27.078125 171.15277 27.578125 171.8559Q28.078125 172.55902 28.796875 172.55902Q29.53125 172.55902 30.015625 171.8559Q30.515625 171.15277 30.515625 169.0434Q30.515625 166.9184 30.015625 166.2309Q29.53125 165.52777 28.78125 165.52777Q28.0625 165.52777 27.625 166.13715Q27.078125 166.9184 27.078125 169.0434ZM33.0 169.0434Q33.0 167.51215 33.3125 166.59027Q33.625 165.65277 34.234375 165.15277Q34.859375 164.65277 35.796875 164.65277Q36.484375 164.65277 37.0 164.93402Q37.53125 165.21527 37.875 165.74652Q38.21875 166.26215 38.40625 167.01215Q38.59375 167.76215 38.59375 169.0434Q38.59375 170.55902 38.28125 171.4809Q37.984375 172.40277 37.359375 172.9184Q36.75 173.4184 35.796875 173.4184Q34.5625 173.4184 33.84375 172.52777Q33.0 171.46527 33.0 169.0434ZM34.078125 169.0434Q34.078125 171.15277 34.578125 171.8559Q35.078125 172.55902 35.796875 172.55902Q36.53125 172.55902 37.015625 171.8559Q37.515625 171.15277 37.515625 169.0434Q37.515625 166.9184 37.015625 166.2309Q36.53125 165.52777 35.78125 165.52777Q35.0625 165.52777 34.625 166.13715Q34.078125 166.9184 34.078125 169.0434ZM40.59375 173.27777L40.59375 172.07465L41.796875 172.07465L41.796875 173.27777L40.59375 173.27777ZM43.0 169.0434Q43.0 167.51215 43.3125 166.59027Q43.625 165.65277 44.234375 165.15277Q44.859375 164.65277 45.796875 164.65277Q46.484375 164.65277 47.0 164.93402Q47.53125 165.21527 47.875 165.74652Q48.21875 166.26215 48.40625 167.01215Q48.59375 167.76215 48.59375 169.0434Q48.59375 170.55902 48.28125 171.4809Q47.984375 172.40277 47.359375 172.9184Q46.75 173.4184 45.796875 173.4184Q44.5625 173.4184 43.84375 172.52777Q43.0 171.46527 43.0 169.0434ZM44.078125 169.0434Q44.078125 171.15277 44.578125 171.8559Q45.078125 172.55902 45.796875 172.55902Q46.53125 172.55902 47.015625 171.8559Q47.515625 171.15277 47.515625 169.0434Q47.515625 166.9184 47.015625 166.2309Q46.53125 165.52777 45.78125 165.52777Q45.0625 165.52777 44.625 166.13715Q44.078125 166.9184 44.078125 169.0434ZM50.0 169.0434Q50.0 167.51215 50.3125 166.59027Q50.625 165.65277 51.234375 165.15277Q51.859375 164.65277 52.796875 164.65277Q53.484375 164.65277 54.0 164.93402Q54.53125 165.21527 54.875 165.74652Q55.21875 166.26215 55.40625 167.01215Q55.59375 167.76215 55.59375 169.0434Q55.59375 170.55902 55.28125 171.4809Q54.984375 172.40277 54.359375 172.9184Q53.75 173.4184 52.796875 173.4184Q51.5625 173.4184 50.84375 172.52777Q50.0 171.46527 50.0 169.0434ZM51.078125 169.0434Q51.078125 171.15277 51.578125 171.8559Q52.078125 172.55902 52.796875 172.55902Q53.53125 172.55902 54.015625 171.8559Q54.515625 171.15277 54.515625 169.0434Q54.515625 166.9184 54.015625 166.2309Q53.53125 165.52777 52.78125 165.52777Q52.0625 165.52777 51.625 166.13715Q51.078125 166.9184 51.078125 169.0434ZM57.203125 166.74652Q57.203125 165.82465 57.65625 165.18402Q58.125 164.5434 59.0 164.5434Q59.8125 164.5434 60.34375 165.12152Q60.875 165.69965 60.875 166.80902Q60.875 167.90277 60.328125 168.49652Q59.796875 169.07465 59.015625 169.07465Q58.234375 169.07465 57.71875 168.49652Q57.203125 167.9184 57.203125 166.74652ZM59.03125 165.26215Q58.640625 165.26215 58.375 165.6059Q58.125 165.94965 58.125 166.8559Q58.125 167.68402 58.375 168.02777Q58.640625 168.3559 59.03125 168.3559Q59.4375 168.3559 59.6875 168.01215Q59.953125 167.6684 59.953125 166.77777Q59.953125 165.93402 59.6875 165.6059Q59.421875 165.26215 59.03125 165.26215ZM59.03125 173.59027L63.734375 164.5434L64.59375 164.5434L59.90625 173.59027L59.03125 173.59027ZM62.75 171.26215Q62.75 170.34027 63.203125 169.69965Q63.671875 169.05902 64.5625 169.05902Q65.375 169.05902 65.90625 169.63715Q66.4375 170.19965 66.4375 171.32465Q66.4375 172.4184 65.890625 173.01215Q65.359375 173.59027 64.5625 173.59027Q63.796875 173.59027 63.265625 173.01215Q62.75 172.43402 62.75 171.26215ZM64.59375 169.77777Q64.1875 169.77777 63.921875 170.12152Q63.671875 170.46527 63.671875 171.37152Q63.671875 172.18402 63.9375 172.52777Q64.203125 172.87152 64.59375 172.87152Q64.984375 172.87152 65.25 172.52777Q65.515625 172.18402 65.515625 171.27777Q65.515625 170.44965 65.25 170.12152Q64.984375 169.77777 64.59375 169.77777Z" fill-rule="nonzero"/><path fill="#000000" d="M22.96875 92.166664L21.921875 92.166664L21.921875 85.447914Q21.53125 85.80729 20.90625 86.18229Q20.296875 86.541664 19.8125 86.71354L19.8125 85.697914Q20.6875 85.27604 21.34375 84.697914Q22.015625 84.104164 22.296875 83.541664L22.96875 83.541664L22.96875 92.166664ZM26.0 89.916664L27.109375 89.822914Q27.234375 90.635414 27.671875 91.041664Q28.125 91.447914 28.765625 91.447914Q29.515625 91.447914 30.046875 90.86979Q30.578125 90.291664 30.578125 89.354164Q30.578125 88.447914 30.0625 87.93229Q29.5625 87.40104 28.734375 87.40104Q28.234375 87.40104 27.8125 87.635414Q27.40625 87.86979 27.171875 88.229164L26.1875 88.104164L27.015625 83.697914L31.296875 83.697914L31.296875 84.697914L27.859375 84.697914L27.40625 87.010414Q28.171875 86.46354 29.015625 86.46354Q30.140625 86.46354 30.90625 87.24479Q31.6875 88.02604 31.6875 89.260414Q31.6875 90.416664 31.015625 91.27604Q30.1875 92.30729 28.765625 92.30729Q27.59375 92.30729 26.84375 91.65104Q26.109375 90.99479 26.0 89.916664ZM33.0 87.93229Q33.0 86.40104 33.3125 85.479164Q33.625 84.541664 34.234375 84.041664Q34.859375 83.541664 35.796875 83.541664Q36.484375 83.541664 37.0 83.822914Q37.53125 84.104164 37.875 84.635414Q38.21875 85.15104 38.40625 85.90104Q38.59375 86.65104 38.59375 87.93229Q38.59375 89.447914 38.28125 90.36979Q37.984375 91.291664 37.359375 91.80729Q36.75 92.30729 35.796875 92.30729Q34.5625 92.30729 33.84375 91.416664Q33.0 90.354164 33.0 87.93229ZM34.078125 87.93229Q34.078125 90.041664 34.578125 90.74479Q35.078125 91.447914 35.796875 91.447914Q36.53125 91.447914 37.015625 90.74479Q37.515625 90.041664 37.515625 87.93229Q37.515625 85.80729 37.015625 85.11979Q36.53125 84.416664 35.78125 84.416664Q35.0625 84.416664 34.625 85.02604Q34.078125 85.80729 34.078125 87.93229ZM40.59375 92.166664L40.59375 90.96354L41.796875 90.96354L41.796875 92.166664L40.59375 92.166664ZM43.0 87.93229Q43.0 86.40104 43.3125 85.479164Q43.625 84.541664 44.234375 84.041664Q44.859375 83.541664 45.796875 83.541664Q46.484375 83.541664 47.0 83.822914Q47.53125 84.104164 47.875 84.635414Q48.21875 85.15104 48.40625 85.90104Q48.59375 86.65104 48.59375 87.93229Q48.59375 89.447914 48.28125 90.36979Q47.984375 91.291664 47.359375 91.80729Q46.75 92.30729 45.796875 92.30729Q44.5625 92.30729 43.84375 91.416664Q43.0 90.354164 43.0 87.93229ZM44.078125 87.93229Q44.078125 90.041664 44.578125 90.74479Q45.078125 91.447914 45.796875 91.447914Q46.53125 91.447914 47.015625 90.74479Q47.515625 90.041664 47.515625 87.93229Q47.515625 85.80729 47.015625 85.11979Q46.53125 84.416664 45.78125 84.416664Q45.0625 84.416664 44.625 85.02604Q44.078125 85.80729 44.078125 87.93229ZM50.0 87.93229Q50.0 86.40104 50.3125 85.479164Q50.625 84.541664 51.234375 84.041664Q51.859375 83.541664 52.796875 83.541664Q53.484375 83.541664 54.0 83.822914Q54.53125 84.104164 54.875 84.635414Q55.21875 85.15104 55.40625 85.90104Q55.59375 86.65104 55.59375 87.93229Q55.59375 89.447914 55.28125 90.36979Q54.984375 91.291664 54.359375 91.80729Q53.75 92.30729 52.796875 92.30729Q51.5625 92.30729 50.84375 91.416664Q50.0 90.354164 50.0 87.93229ZM51.078125 87.93229Q51.078125 90.041664 51.578125 90.74479Q52.078125 91.447914 52.796875 91.447914Q53.53125 91.447914 54.015625 90.74479Q54.515625 90.041664 54.515625 87.93229Q54.515625 85.80729 54.015625 85.11979Q53.53125 84.416664 52.78125 84.416664Q52.0625 84.416664 51.625 85.02604Q51.078125 85.80729 51.078125 87.93229ZM57.203125 85.635414Q57.203125 84.71354 57.65625 84.072914Q58.125 83.43229 59.0 83.43229Q59.8125 83.43229 60.34375 84.010414Q60.875 84.58854 60.875 85.697914Q60.875 86.791664 60.328125 87.385414Q59.796875 87.96354 59.015625 87.96354Q58.234375 87.96354 57.71875 87.385414Q57.203125 86.80729 57.203125 85.635414ZM59.03125 84.15104Q58.640625 84.15104 58.375 84.49479Q58.125 84.83854 58.125 85.74479Q58.125 86.572914 58.375 86.916664Q58.640625 87.24479 59.03125 87.24479Q59.4375 87.24479 59.6875 86.90104Q59.953125 86.55729 59.953125 85.666664Q59.953125 84.822914 59.6875 84.49479Q59.421875 84.15104 59.03125 84.15104ZM59.03125 92.479164L63.734375 83.43229L64.59375 83.43229L59.90625 92.479164L59.03125 92.479164ZM62.75 90.15104Q62.75 89.229164 63.203125 88.58854Q63.671875 87.947914 64.5625 87.947914Q65.375 87.947914 65.90625 88.52604Q66.4375 89.08854 66.4375 90.21354Q66.4375 91.30729 65.890625 91.90104Q65.359375 92.479164 64.5625 92.479164Q63.796875 92.479164 63.265625 91.90104Q62.75 91.322914 62.75 90.15104ZM64.59375 88.666664Q64.1875 88.666664 63.921875 89.010414Q63.671875 89.354164 63.671875 90.260414Q63.671875 91.072914 63.9375 91.416664Q64.203125 91.760414 64.59375 91.760414Q64.984375 91.760414 65.25 91.416664Q65.515625 91.072914 65.515625 90.166664Q65.515625 89.33854 65.25 89.010414Q64.984375 88.666664 64.59375 88.666664Z" fill-rule="nonzero"/><path fill="#000000" d="M130.11774 345.73438L131.18024 345.64062Q131.25836 346.29688 131.53961 346.70312Q131.82086 347.10938 132.39899 347.375Q132.99274 347.625 133.72711 347.625Q134.36774 347.625 134.86774 347.4375Q135.36774 347.23438 135.60211 346.90625Q135.85211 346.5625 135.85211 346.17188Q135.85211 345.76562 135.61774 345.46875Q135.38336 345.15625 134.85211 344.95312Q134.49274 344.8125 133.30524 344.53125Q132.13336 344.25 131.66461 344.0Q131.03961 343.67188 130.74274 343.20312Q130.44586 342.71875 130.44586 342.125Q130.44586 341.48438 130.80524 340.92188Q131.18024 340.34375 131.88336 340.0625Q132.60211 339.76562 133.46149 339.76562Q134.41461 339.76562 135.14899 340.07812Q135.88336 340.375 136.27399 340.98438Q136.66461 341.57812 136.69586 342.32812L135.60211 342.40625Q135.50836 341.59375 134.99274 341.1875Q134.49274 340.76562 133.50836 340.76562Q132.47711 340.76562 132.00836 341.14062Q131.53961 341.51562 131.53961 342.04688Q131.53961 342.51562 131.86774 342.8125Q132.19586 343.10938 133.57086 343.42188Q134.96149 343.73438 135.47711 343.96875Q136.22711 344.32812 136.58649 344.85938Q136.94586 345.375 136.94586 346.07812Q136.94586 346.76562 136.55524 347.375Q136.16461 347.96875 135.43024 348.3125Q134.69586 348.64062 133.77399 348.64062Q132.60211 348.64062 131.80524 348.3125Q131.02399 347.96875 130.57086 347.28125Q130.13336 346.59375 130.11774 345.73438ZM137.97711 345.39062Q137.97711 343.65625 138.93024 342.82812Q139.72711 342.14062 140.88336 342.14062Q142.16461 342.14062 142.97711 342.98438Q143.80524 343.8125 143.80524 345.29688Q143.80524 346.5 143.44586 347.1875Q143.08649 347.875 142.38336 348.26562Q141.69586 348.64062 140.88336 348.64062Q139.58649 348.64062 138.77399 347.8125Q137.97711 346.96875 137.97711 345.39062ZM139.05524 345.39062Q139.05524 346.57812 139.57086 347.17188Q140.10211 347.76562 140.88336 347.76562Q141.68024 347.76562 142.19586 347.17188Q142.71149 346.57812 142.71149 345.35938Q142.71149 344.20312 142.18024 343.60938Q141.66461 343.01562 140.88336 343.01562Q140.10211 343.01562 139.57086 343.60938Q139.05524 344.1875 139.05524 345.39062ZM146.33649 348.5L145.35211 348.5L145.35211 339.90625L146.41461 339.90625L146.41461 342.96875Q147.08649 342.14062 148.11774 342.14062Q148.69586 342.14062 149.19586 342.375Q149.71149 342.59375 150.03961 343.01562Q150.38336 343.4375 150.57086 344.03125Q150.75836 344.625 150.75836 345.29688Q150.75836 346.89062 149.96149 347.76562Q149.16461 348.64062 148.07086 348.64062Q146.96149 348.64062 146.33649 347.71875L146.33649 348.5ZM146.32086 345.34375Q146.32086 346.45312 146.63336 346.95312Q147.13336 347.76562 147.97711 347.76562Q148.66461 347.76562 149.16461 347.17188Q149.68024 346.57812 149.68024 345.375Q149.68024 344.15625 149.19586 343.57812Q148.71149 343.0 148.02399 343.0Q147.33649 343.0 146.82086 343.60938Q146.32086 344.20312 146.32086 345.34375ZM156.61774 346.5L157.71149 346.625Q157.46149 347.57812 156.75836 348.10938Q156.05524 348.64062 154.97711 348.64062Q153.61774 348.64062 152.80524 347.79688Q152.00836 346.95312 152.00836 345.4375Q152.00836 343.875 152.82086 343.01562Q153.63336 342.14062 154.91461 342.14062Q156.16461 342.14062 156.94586 342.98438Q157.74274 343.82812 157.74274 345.375Q157.74274 345.46875 157.74274 345.65625L153.10211 345.65625Q153.16461 346.6875 153.68024 347.23438Q154.19586 347.76562 154.97711 347.76562Q155.55524 347.76562 155.96149 347.46875Q156.38336 347.15625 156.61774 346.5ZM153.16461 344.79688L156.63336 344.79688Q156.57086 344.0 156.24274 343.60938Q155.72711 343.0 154.93024 343.0Q154.19586 343.0 153.69586 343.48438Q153.21149 343.96875 153.16461 344.79688ZM159.33649 348.5L159.33649 339.90625L160.39899 339.90625L160.39899 348.5L159.33649 348.5Z" fill-rule="nonzero"/><path fill="#000000" d="M241.40501 345.48438L242.53001 345.78125Q242.17064 347.17188 241.24876 347.90625Q240.32689 348.64062 238.98314 348.64062Q237.59251 348.64062 236.71751 348.07812Q235.84251 347.51562 235.38939 346.45312Q234.93626 345.375 234.93626 344.14062Q234.93626 342.79688 235.45189 341.79688Q235.96751 340.79688 236.90501 340.28125Q237.85814 339.76562 238.99876 339.76562Q240.28001 339.76562 241.15501 340.42188Q242.04564 341.07812 242.38939 342.26562L241.26439 342.53125Q240.96751 341.59375 240.38939 341.17188Q239.82689 340.73438 238.96751 340.73438Q237.98314 340.73438 237.31126 341.21875Q236.65501 341.6875 236.37376 342.48438Q236.10814 343.28125 236.10814 344.14062Q236.10814 345.23438 236.42064 346.04688Q236.74876 346.85938 237.42064 347.26562Q238.09251 347.67188 238.88939 347.67188Q239.84251 347.67188 240.49876 347.125Q241.17064 346.57812 241.40501 345.48438ZM248.20189 347.73438Q247.60814 348.23438 247.06126 348.4375Q246.53001 348.64062 245.90501 348.64062Q244.87376 348.64062 244.32689 348.14062Q243.78001 347.64062 243.78001 346.85938Q243.78001 346.40625 243.98314 346.03125Q244.18626 345.64062 244.53001 345.42188Q244.87376 345.1875 245.29564 345.07812Q245.59251 344.98438 246.23314 344.90625Q247.49876 344.76562 248.10814 344.54688Q248.10814 344.32812 248.10814 344.28125Q248.10814 343.625 247.81126 343.35938Q247.40501 343.01562 246.60814 343.01562Q245.87376 343.01562 245.51439 343.28125Q245.15501 343.53125 244.98314 344.1875L243.95189 344.04688Q244.09251 343.39062 244.42064 342.98438Q244.74876 342.57812 245.35814 342.35938Q245.96751 342.14062 246.76439 342.14062Q247.56126 342.14062 248.06126 342.32812Q248.56126 342.51562 248.79564 342.79688Q249.03001 343.07812 249.12376 343.51562Q249.17064 343.78125 249.17064 344.48438L249.17064 345.89062Q249.17064 347.35938 249.23314 347.75Q249.31126 348.14062 249.51439 348.5L248.40501 348.5Q248.24876 348.17188 248.20189 347.73438ZM248.10814 345.375Q247.53001 345.60938 246.38939 345.78125Q245.73314 345.875 245.46751 346.0Q245.20189 346.10938 245.04564 346.32812Q244.90501 346.54688 244.90501 346.82812Q244.90501 347.25 245.21751 347.53125Q245.54564 347.8125 246.15501 347.8125Q246.76439 347.8125 247.23314 347.54688Q247.71751 347.28125 247.93626 346.8125Q248.10814 346.45312 248.10814 345.76562L248.10814 345.375ZM251.13939 348.5L251.13939 342.28125L252.07689 342.28125L252.07689 343.15625Q252.76439 342.14062 254.06126 342.14062Q254.62376 342.14062 255.09251 342.34375Q255.57689 342.54688 255.81126 342.875Q256.04565 343.20312 256.1394 343.64062Q256.18628 343.9375 256.18628 344.67188L256.18628 348.5L255.13939 348.5L255.13939 344.71875Q255.13939 344.0625 255.01439 343.75Q254.88939 343.4375 254.57689 343.25Q254.26439 343.04688 253.84251 343.04688Q253.17064 343.04688 252.67064 343.48438Q252.18626 343.90625 252.18626 345.09375L252.18626 348.5L251.13939 348.5ZM258.1394 348.5L258.1394 342.28125L259.0769 342.28125L259.0769 343.15625Q259.7644 342.14062 261.06128 342.14062Q261.62378 342.14062 262.09253 342.34375Q262.5769 342.54688 262.81128 342.875Q263.04565 343.20312 263.1394 343.64062Q263.18628 343.9375 263.18628 344.67188L263.18628 348.5L262.1394 348.5L262.1394 344.71875Q262.1394 344.0625 262.0144 343.75Q261.8894 343.4375 261.5769 343.25Q261.2644 343.04688 260.84253 343.04688Q260.17065 343.04688 259.67065 343.48438Q259.18628 343.90625 259.18628 345.09375L259.18628 348.5L258.1394 348.5ZM265.09253 350.89062L264.96753 349.90625Q265.31128 350.0 265.5769 350.0Q265.92065 350.0 266.12378 349.875Q266.34253 349.76562 266.48315 349.5625Q266.5769 349.39062 266.81128 348.76562Q266.8269 348.6875 266.90503 348.51562L264.53003 342.28125L265.67065 342.28125L266.96753 345.875Q267.21753 346.5625 267.42065 347.32812Q267.60815 346.59375 267.85815 345.90625L269.18628 342.28125L270.23315 342.28125L267.87378 348.60938Q267.48315 349.625 267.28003 350.01562Q266.99878 350.54688 266.62378 350.78125Q266.2644 351.03125 265.7644 351.03125Q265.46753 351.03125 265.09253 350.89062Z" fill-rule="nonzero"/><path fill="#000000" d="M315.16104 345.73438L316.22354 345.64062Q316.30167 346.29688 316.58292 346.70312Q316.86417 347.10938 317.4423 347.375Q318.03604 347.625 318.77042 347.625Q319.41104 347.625 319.91104 347.4375Q320.41104 347.23438 320.64542 346.90625Q320.89542 346.5625 320.89542 346.17188Q320.89542 345.76562 320.66104 345.46875Q320.42667 345.15625 319.89542 344.95312Q319.53604 344.8125 318.34854 344.53125Q317.17667 344.25 316.70792 344.0Q316.08292 343.67188 315.78604 343.20312Q315.48917 342.71875 315.48917 342.125Q315.48917 341.48438 315.84854 340.92188Q316.22354 340.34375 316.92667 340.0625Q317.64542 339.76562 318.5048 339.76562Q319.45792 339.76562 320.1923 340.07812Q320.92667 340.375 321.3173 340.98438Q321.70792 341.57812 321.73917 342.32812L320.64542 342.40625Q320.55167 341.59375 320.03604 341.1875Q319.53604 340.76562 318.55167 340.76562Q317.52042 340.76562 317.05167 341.14062Q316.58292 341.51562 316.58292 342.04688Q316.58292 342.51562 316.91104 342.8125Q317.23917 343.10938 318.61417 343.42188Q320.0048 343.73438 320.52042 343.96875Q321.27042 344.32812 321.6298 344.85938Q321.98917 345.375 321.98917 346.07812Q321.98917 346.76562 321.59854 347.375Q321.20792 347.96875 320.47354 348.3125Q319.73917 348.64062 318.8173 348.64062Q317.64542 348.64062 316.84854 348.3125Q316.0673 347.96875 315.61417 347.28125Q315.17667 346.59375 315.16104 345.73438ZM325.70792 347.5625L325.86417 348.48438Q325.41104 348.57812 325.0673 348.57812Q324.48917 348.57812 324.17667 348.40625Q323.86417 348.21875 323.72354 347.92188Q323.59854 347.625 323.59854 346.67188L323.59854 343.09375L322.83292 343.09375L322.83292 342.28125L323.59854 342.28125L323.59854 340.73438L324.64542 340.10938L324.64542 342.28125L325.70792 342.28125L325.70792 343.09375L324.64542 343.09375L324.64542 346.73438Q324.64542 347.1875 324.6923 347.3125Q324.7548 347.4375 324.8798 347.51562Q325.0048 347.59375 325.23917 347.59375Q325.42667 347.59375 325.70792 347.5625ZM330.66104 346.5L331.7548 346.625Q331.5048 347.57812 330.80167 348.10938Q330.09854 348.64062 329.02042 348.64062Q327.66104 348.64062 326.84854 347.79688Q326.05167 346.95312 326.05167 345.4375Q326.05167 343.875 326.86417 343.01562Q327.67667 342.14062 328.95792 342.14062Q330.20792 342.14062 330.98917 342.98438Q331.78604 343.82812 331.78604 345.375Q331.78604 345.46875 331.78604 345.65625L327.14542 345.65625Q327.20792 346.6875 327.72354 347.23438Q328.23917 347.76562 329.02042 347.76562Q329.59854 347.76562 330.0048 347.46875Q330.42667 347.15625 330.66104 346.5ZM327.20792 344.79688L330.67667 344.79688Q330.61417 344.0 330.28604 343.60938Q329.77042 343.0 328.97354 343.0Q328.23917 343.0 327.73917 343.48438Q327.2548 343.96875 327.20792 344.79688ZM333.39542 348.5L333.39542 342.28125L334.34854 342.28125L334.34854 343.21875Q334.70792 342.5625 335.0048 342.35938Q335.3173 342.14062 335.6923 342.14062Q336.22354 342.14062 336.77042 342.46875L336.41104 343.45312Q336.02042 343.21875 335.64542 343.21875Q335.28604 343.21875 335.0048 343.4375Q334.73917 343.64062 334.6298 344.01562Q334.4423 344.57812 334.4423 345.23438L334.4423 348.5L333.39542 348.5ZM341.66104 346.5L342.7548 346.625Q342.5048 347.57812 341.80167 348.10938Q341.09854 348.64062 340.02042 348.64062Q338.66104 348.64062 337.84854 347.79688Q337.05167 346.95312 337.05167 345.4375Q337.05167 343.875 337.86417 343.01562Q338.67667 342.14062 339.95792 342.14062Q341.20792 342.14062 341.98917 342.98438Q342.78604 343.82812 342.78604 345.375Q342.78604 345.46875 342.78604 345.65625L338.14542 345.65625Q338.20792 346.6875 338.72354 347.23438Q339.23917 347.76562 340.02042 347.76562Q340.59854 347.76562 341.0048 347.46875Q341.42667 347.15625 341.66104 346.5ZM338.20792 344.79688L341.67667 344.79688Q341.61417 344.0 341.28604 343.60938Q340.77042 343.0 339.97354 343.0Q339.23917 343.0 338.73917 343.48438Q338.2548 343.96875 338.20792 344.79688ZM344.02042 345.39062Q344.02042 343.65625 344.97354 342.82812Q345.77042 342.14062 346.92667 342.14062Q348.20792 342.14062 349.02042 342.98438Q349.84854 343.8125 349.84854 345.29688Q349.84854 346.5 349.48917 347.1875Q349.1298 347.875 348.42667 348.26562Q347.73917 348.64062 346.92667 348.64062Q345.6298 348.64062 344.8173 347.8125Q344.02042 346.96875 344.02042 345.39062ZM345.09854 345.39062Q345.09854 346.57812 345.61417 347.17188Q346.14542 347.76562 346.92667 347.76562Q347.72354 347.76562 348.23917 347.17188Q348.7548 346.57812 348.7548 345.35938Q348.7548 344.20312 348.22354 343.60938Q347.70792 343.01562 346.92667 343.01562Q346.14542 343.01562 345.61417 343.60938Q345.09854 344.1875 345.09854 345.39062ZM354.5048 348.5L354.5048 339.90625L356.22354 339.90625L358.2548 345.98438Q358.53604 346.84375 358.66104 347.26562Q358.80167 346.79688 359.11417 345.89062L361.17667 339.90625L362.70792 339.90625L362.70792 348.5L361.61417 348.5L361.61417 341.3125L359.11417 348.5L358.08292 348.5L355.59854 341.1875L355.59854 348.5L354.5048 348.5ZM368.47354 347.73438Q367.8798 348.23438 367.33292 348.4375Q366.80167 348.64062 366.17667 348.64062Q365.14542 348.64062 364.59854 348.14062Q364.05167 347.64062 364.05167 346.85938Q364.05167 346.40625 364.2548 346.03125Q364.45792 345.64062 364.80167 345.42188Q365.14542 345.1875 365.5673 345.07812Q365.86417 344.98438 366.5048 344.90625Q367.77042 344.76562 368.3798 344.54688Q368.3798 344.32812 368.3798 344.28125Q368.3798 343.625 368.08292 343.35938Q367.67667 343.01562 366.8798 343.01562Q366.14542 343.01562 365.78604 343.28125Q365.42667 343.53125 365.2548 344.1875L364.22354 344.04688Q364.36417 343.39062 364.6923 342.98438Q365.02042 342.57812 365.6298 342.35938Q366.23917 342.14062 367.03604 342.14062Q367.83292 342.14062 368.33292 342.32812Q368.83292 342.51562 369.0673 342.79688Q369.30167 343.07812 369.39542 343.51562Q369.4423 343.78125 369.4423 344.48438L369.4423 345.89062Q369.4423 347.35938 369.5048 347.75Q369.58292 348.14062 369.78604 348.5L368.67667 348.5Q368.52042 348.17188 368.47354 347.73438ZM368.3798 345.375Q367.80167 345.60938 366.66104 345.78125Q366.0048 345.875 365.73917 346.0Q365.47354 346.10938 365.3173 346.32812Q365.17667 346.54688 365.17667 346.82812Q365.17667 347.25 365.48917 347.53125Q365.8173 347.8125 366.42667 347.8125Q367.03604 347.8125 367.5048 347.54688Q367.98917 347.28125 368.20792 346.8125Q368.3798 346.45312 368.3798 345.76562L368.3798 345.375ZM373.70792 347.5625L373.86417 348.48438Q373.41104 348.57812 373.0673 348.57812Q372.48917 348.57812 372.17667 348.40625Q371.86417 348.21875 371.72354 347.92188Q371.59854 347.625 371.59854 346.67188L371.59854 343.09375L370.83292 343.09375L370.83292 342.28125L371.59854 342.28125L371.59854 340.73438L372.64542 340.10938L372.64542 342.28125L373.70792 342.28125L373.70792 343.09375L372.64542 343.09375L372.64542 346.73438Q372.64542 347.1875 372.6923 347.3125Q372.7548 347.4375 372.8798 347.51562Q373.0048 347.59375 373.23917 347.59375Q373.42667 347.59375 373.70792 347.5625ZM378.47354 346.21875L379.5048 346.35938Q379.33292 347.42188 378.6298 348.03125Q377.92667 348.64062 376.91104 348.64062Q375.6298 348.64062 374.84854 347.8125Q374.08292 346.96875 374.08292 345.40625Q374.08292 344.40625 374.41104 343.65625Q374.7548 342.89062 375.42667 342.51562Q376.11417 342.14062 376.92667 342.14062Q377.92667 342.14062 378.5673 342.65625Q379.22354 343.15625 379.41104 344.10938L378.3798 344.26562Q378.23917 343.64062 377.86417 343.32812Q377.48917 343.0 376.95792 343.0Q376.16104 343.0 375.66104 343.57812Q375.16104 344.14062 375.16104 345.375Q375.16104 346.64062 375.64542 347.20312Q376.1298 347.76562 376.89542 347.76562Q377.52042 347.76562 377.92667 347.39062Q378.34854 347.01562 378.47354 346.21875ZM380.41104 348.5L380.41104 339.90625L381.45792 339.90625L381.45792 342.98438Q382.1923 342.14062 383.3173 342.14062Q384.02042 342.14062 384.52042 342.42188Q385.03604 342.6875 385.2548 343.17188Q385.47354 343.64062 385.47354 344.5625L385.47354 348.5L384.42667 348.5L384.42667 344.5625Q384.42667 343.76562 384.08292 343.40625Q383.73917 343.04688 383.11417 343.04688Q382.64542 343.04688 382.22354 343.29688Q381.8173 343.53125 381.6298 343.95312Q381.45792 344.35938 381.45792 345.09375L381.45792 348.5L380.41104 348.5ZM387.41104 341.125L387.41104 339.90625L388.47354 339.90625L388.47354 341.125L387.41104 341.125ZM387.41104 348.5L387.41104 342.28125L388.47354 342.28125L388.47354 348.5L387.41104 348.5ZM390.41104 348.5L390.41104 342.28125L391.34854 342.28125L391.34854 343.15625Q392.03604 342.14062 393.33292 342.14062Q393.89542 342.14062 394.36417 342.34375Q394.84854 342.54688 395.08292 342.875Q395.3173 343.20312 395.41104 343.64062Q395.45792 343.9375 395.45792 344.67188L395.45792 348.5L394.41104 348.5L394.41104 344.71875Q394.41104 344.0625 394.28604 343.75Q394.16104 343.4375 393.84854 343.25Q393.53604 343.04688 393.11417 343.04688Q392.4423 343.04688 391.9423 343.48438Q391.45792 343.90625 391.45792 345.09375L391.45792 348.5L390.41104 348.5ZM397.20792 349.01562L398.23917 349.17188Q398.30167 349.64062 398.59854 349.85938Q398.98917 350.15625 399.66104 350.15625Q400.39542 350.15625 400.78604 349.85938Q401.1923 349.5625 401.33292 349.04688Q401.42667 348.71875 401.41104 347.6875Q400.72354 348.5 399.6923 348.5Q398.41104 348.5 397.70792 347.57812Q397.0048 346.64062 397.0048 345.35938Q397.0048 344.46875 397.3173 343.71875Q397.64542 342.95312 398.2548 342.54688Q398.86417 342.14062 399.6923 342.14062Q400.80167 342.14062 401.52042 343.03125L401.52042 342.28125L402.48917 342.28125L402.48917 347.65625Q402.48917 349.10938 402.1923 349.71875Q401.89542 350.32812 401.2548 350.67188Q400.61417 351.03125 399.67667 351.03125Q398.5673 351.03125 397.8798 350.53125Q397.1923 350.03125 397.20792 349.01562ZM398.08292 345.28125Q398.08292 346.5 398.5673 347.0625Q399.05167 347.625 399.78604 347.625Q400.52042 347.625 401.0048 347.0625Q401.5048 346.5 401.5048 345.3125Q401.5048 344.17188 400.98917 343.59375Q400.48917 343.01562 399.77042 343.01562Q399.0673 343.01562 398.5673 343.59375Q398.08292 344.15625 398.08292 345.28125Z" fill-rule="nonzero"/><path fill="#000000" d="M432.33896 345.125L432.33896 344.125L435.96396 344.10938L435.96396 347.29688Q435.13583 347.96875 434.2452 348.3125Q433.35458 348.64062 432.41708 348.64062Q431.15146 348.64062 430.10458 348.10938Q429.07333 347.5625 428.54208 346.54688Q428.02646 345.51562 428.02646 344.25Q428.02646 342.98438 428.54208 341.90625Q429.07333 340.8125 430.0577 340.29688Q431.04208 339.76562 432.32333 339.76562Q433.26083 339.76562 434.01083 340.0625Q434.76083 340.35938 435.1827 340.90625Q435.6202 341.4375 435.83896 342.3125L434.82333 342.59375Q434.6202 341.9375 434.32333 341.5625Q434.04208 341.1875 433.51083 340.96875Q432.97958 340.73438 432.33896 340.73438Q431.5577 340.73438 430.97958 340.96875Q430.41708 341.20312 430.0577 341.59375Q429.71396 341.98438 429.52646 342.45312Q429.19833 343.25 429.19833 344.17188Q429.19833 345.32812 429.58896 346.10938Q429.9952 346.875 430.7452 347.25Q431.4952 347.625 432.35458 347.625Q433.08896 347.625 433.79208 347.34375Q434.4952 347.04688 434.85458 346.73438L434.85458 345.125L432.33896 345.125ZM441.2452 347.73438Q440.65146 348.23438 440.10458 348.4375Q439.57333 348.64062 438.94833 348.64062Q437.91708 348.64062 437.3702 348.14062Q436.82333 347.64062 436.82333 346.85938Q436.82333 346.40625 437.02646 346.03125Q437.22958 345.64062 437.57333 345.42188Q437.91708 345.1875 438.33896 345.07812Q438.63583 344.98438 439.27646 344.90625Q440.54208 344.76562 441.15146 344.54688Q441.15146 344.32812 441.15146 344.28125Q441.15146 343.625 440.85458 343.35938Q440.44833 343.01562 439.65146 343.01562Q438.91708 343.01562 438.5577 343.28125Q438.19833 343.53125 438.02646 344.1875L436.9952 344.04688Q437.13583 343.39062 437.46396 342.98438Q437.79208 342.57812 438.40146 342.35938Q439.01083 342.14062 439.8077 342.14062Q440.60458 342.14062 441.10458 342.32812Q441.60458 342.51562 441.83896 342.79688Q442.07333 343.07812 442.16708 343.51562Q442.21396 343.78125 442.21396 344.48438L442.21396 345.89062Q442.21396 347.35938 442.27646 347.75Q442.35458 348.14062 442.5577 348.5L441.44833 348.5Q441.29208 348.17188 441.2452 347.73438ZM441.15146 345.375Q440.57333 345.60938 439.4327 345.78125Q438.77646 345.875 438.51083 346.0Q438.2452 346.10938 438.08896 346.32812Q437.94833 346.54688 437.94833 346.82812Q437.94833 347.25 438.26083 347.53125Q438.58896 347.8125 439.19833 347.8125Q439.8077 347.8125 440.27646 347.54688Q440.76083 347.28125 440.97958 346.8125Q441.15146 346.45312 441.15146 345.76562L441.15146 345.375ZM448.26083 348.5L448.26083 347.57812Q447.52646 348.64062 446.27646 348.64062Q445.72958 348.64062 445.2452 348.4375Q444.77646 348.21875 444.54208 347.90625Q444.3077 347.57812 444.21396 347.10938Q444.15146 346.8125 444.15146 346.125L444.15146 342.28125L445.21396 342.28125L445.21396 345.73438Q445.21396 346.54688 445.27646 346.84375Q445.3702 347.25 445.6827 347.5Q446.01083 347.73438 446.4952 347.73438Q446.96396 347.73438 447.3702 347.5Q447.79208 347.25 447.96396 346.82812Q448.15146 346.40625 448.15146 345.60938L448.15146 342.28125L449.19833 342.28125L449.19833 348.5L448.26083 348.5ZM450.76083 346.64062L451.79208 346.48438Q451.88583 347.10938 452.27646 347.4375Q452.6827 347.76562 453.41708 347.76562Q454.13583 347.76562 454.47958 347.48438Q454.83896 347.1875 454.83896 346.78125Q454.83896 346.42188 454.52646 346.21875Q454.3077 346.07812 453.44833 345.85938Q452.29208 345.5625 451.83896 345.35938Q451.40146 345.14062 451.16708 344.76562Q450.9327 344.39062 450.9327 343.92188Q450.9327 343.51562 451.1202 343.15625Q451.3077 342.79688 451.63583 342.5625Q451.88583 342.39062 452.3077 342.26562Q452.72958 342.14062 453.22958 342.14062Q453.94833 342.14062 454.4952 342.35938Q455.0577 342.5625 455.32333 342.92188Q455.58896 343.28125 455.6827 343.875L454.65146 344.01562Q454.58896 343.54688 454.2452 343.28125Q453.91708 343.0 453.29208 343.0Q452.57333 343.0 452.26083 343.25Q451.94833 343.48438 451.94833 343.8125Q451.94833 344.01562 452.07333 344.17188Q452.21396 344.34375 452.47958 344.45312Q452.63583 344.51562 453.41708 344.71875Q454.54208 345.03125 454.97958 345.21875Q455.41708 345.40625 455.66708 345.76562Q455.91708 346.125 455.91708 346.67188Q455.91708 347.20312 455.60458 347.67188Q455.3077 348.125 454.72958 348.39062Q454.15146 348.64062 453.41708 348.64062Q452.19833 348.64062 451.5577 348.14062Q450.9327 347.625 450.76083 346.64062ZM456.76083 346.64062L457.79208 346.48438Q457.88583 347.10938 458.27646 347.4375Q458.6827 347.76562 459.41708 347.76562Q460.13583 347.76562 460.47958 347.48438Q460.83896 347.1875 460.83896 346.78125Q460.83896 346.42188 460.52646 346.21875Q460.3077 346.07812 459.44833 345.85938Q458.29208 345.5625 457.83896 345.35938Q457.40146 345.14062 457.16708 344.76562Q456.9327 344.39062 456.9327 343.92188Q456.9327 343.51562 457.1202 343.15625Q457.3077 342.79688 457.63583 342.5625Q457.88583 342.39062 458.3077 342.26562Q458.72958 342.14062 459.22958 342.14062Q459.94833 342.14062 460.4952 342.35938Q461.0577 342.5625 461.32333 342.92188Q461.58896 343.28125 461.6827 343.875L460.65146 344.01562Q460.58896 343.54688 460.2452 343.28125Q459.91708 343.0 459.29208 343.0Q458.57333 343.0 458.26083 343.25Q457.94833 343.48438 457.94833 343.8125Q457.94833 344.01562 458.07333 344.17188Q458.21396 344.34375 458.47958 344.45312Q458.63583 344.51562 459.41708 344.71875Q460.54208 345.03125 460.97958 345.21875Q461.41708 345.40625 461.66708 345.76562Q461.91708 346.125 461.91708 346.67188Q461.91708 347.20312 461.60458 347.67188Q461.3077 348.125 460.72958 348.39062Q460.15146 348.64062 459.41708 348.64062Q458.19833 348.64062 457.5577 348.14062Q456.9327 347.625 456.76083 346.64062ZM463.1827 341.125L463.1827 339.90625L464.2452 339.90625L464.2452 341.125L463.1827 341.125ZM463.1827 348.5L463.1827 342.28125L464.2452 342.28125L464.2452 348.5L463.1827 348.5ZM470.2452 347.73438Q469.65146 348.23438 469.10458 348.4375Q468.57333 348.64062 467.94833 348.64062Q466.91708 348.64062 466.3702 348.14062Q465.82333 347.64062 465.82333 346.85938Q465.82333 346.40625 466.02646 346.03125Q466.22958 345.64062 466.57333 345.42188Q466.91708 345.1875 467.33896 345.07812Q467.63583 344.98438 468.27646 344.90625Q469.54208 344.76562 470.15146 344.54688Q470.15146 344.32812 470.15146 344.28125Q470.15146 343.625 469.85458 343.35938Q469.44833 343.01562 468.65146 343.01562Q467.91708 343.01562 467.5577 343.28125Q467.19833 343.53125 467.02646 344.1875L465.9952 344.04688Q466.13583 343.39062 466.46396 342.98438Q466.79208 342.57812 467.40146 342.35938Q468.01083 342.14062 468.8077 342.14062Q469.60458 342.14062 470.10458 342.32812Q470.60458 342.51562 470.83896 342.79688Q471.07333 343.07812 471.16708 343.51562Q471.21396 343.78125 471.21396 344.48438L471.21396 345.89062Q471.21396 347.35938 471.27646 347.75Q471.35458 348.14062 471.5577 348.5L470.44833 348.5Q470.29208 348.17188 470.2452 347.73438ZM470.15146 345.375Q469.57333 345.60938 468.4327 345.78125Q467.77646 345.875 467.51083 346.0Q467.2452 346.10938 467.08896 346.32812Q466.94833 346.54688 466.94833 346.82812Q466.94833 347.25 467.26083 347.53125Q467.58896 347.8125 468.19833 347.8125Q468.8077 347.8125 469.27646 347.54688Q469.76083 347.28125 469.97958 346.8125Q470.15146 346.45312 470.15146 345.76562L470.15146 345.375ZM473.1827 348.5L473.1827 342.28125L474.1202 342.28125L474.1202 343.15625Q474.8077 342.14062 476.10458 342.14062Q476.66708 342.14062 477.13583 342.34375Q477.6202 342.54688 477.85458 342.875Q478.08896 343.20312 478.1827 343.64062Q478.22958 343.9375 478.22958 344.67188L478.22958 348.5L477.1827 348.5L477.1827 344.71875Q477.1827 344.0625 477.0577 343.75Q476.9327 343.4375 476.6202 343.25Q476.3077 343.04688 475.88583 343.04688Q475.21396 343.04688 474.71396 343.48438Q474.22958 343.90625 474.22958 345.09375L474.22958 348.5L473.1827 348.5ZM483.26083 348.5L483.26083 339.90625L486.4952 339.90625Q487.47958 339.90625 488.07333 340.17188Q488.66708 340.4375 488.9952 340.98438Q489.33896 341.51562 489.33896 342.10938Q489.33896 342.65625 489.04208 343.14062Q488.7452 343.625 488.13583 343.92188Q488.91708 344.15625 489.32333 344.71875Q489.7452 345.26562 489.7452 346.01562Q489.7452 346.60938 489.4952 347.14062Q489.2452 347.65625 488.8702 347.9375Q488.4952 348.21875 487.91708 348.35938Q487.35458 348.5 486.54208 348.5L483.26083 348.5ZM484.40146 343.51562L486.26083 343.51562Q487.01083 343.51562 487.33896 343.42188Q487.77646 343.29688 487.9952 343.0Q488.21396 342.6875 488.21396 342.23438Q488.21396 341.8125 488.01083 341.48438Q487.8077 341.15625 487.41708 341.04688Q487.04208 340.92188 486.1202 340.92188L484.40146 340.92188L484.40146 343.51562ZM484.40146 347.48438L486.54208 347.48438Q487.08896 347.48438 487.3077 347.4375Q487.71396 347.375 487.96396 347.21875Q488.22958 347.04688 488.40146 346.73438Q488.57333 346.42188 488.57333 346.01562Q488.57333 345.53125 488.32333 345.17188Q488.08896 344.8125 487.65146 344.67188Q487.21396 344.53125 486.38583 344.53125L484.40146 344.53125L484.40146 347.48438ZM491.15146 348.5L491.15146 339.90625L492.21396 339.90625L492.21396 348.5L491.15146 348.5ZM498.26083 348.5L498.26083 347.57812Q497.52646 348.64062 496.27646 348.64062Q495.72958 348.64062 495.2452 348.4375Q494.77646 348.21875 494.54208 347.90625Q494.3077 347.57812 494.21396 347.10938Q494.15146 346.8125 494.15146 346.125L494.15146 342.28125L495.21396 342.28125L495.21396 345.73438Q495.21396 346.54688 495.27646 346.84375Q495.3702 347.25 495.6827 347.5Q496.01083 347.73438 496.4952 347.73438Q496.96396 347.73438 497.3702 347.5Q497.79208 347.25 497.96396 346.82812Q498.15146 346.40625 498.15146 345.60938L498.15146 342.28125L499.19833 342.28125L499.19833 348.5L498.26083 348.5ZM501.16708 348.5L501.16708 342.28125L502.1202 342.28125L502.1202 343.21875Q502.47958 342.5625 502.77646 342.35938Q503.08896 342.14062 503.46396 342.14062Q503.9952 342.14062 504.54208 342.46875L504.1827 343.45312Q503.79208 343.21875 503.41708 343.21875Q503.0577 343.21875 502.77646 343.4375Q502.51083 343.64062 502.40146 344.01562Q502.21396 344.57812 502.21396 345.23438L502.21396 348.5L501.16708 348.5Z" fill-rule="nonzero"/><path fill="#000000" d="M535.57935 348.5L535.57935 339.90625L538.5481 339.90625Q539.5481 339.90625 540.07935 340.03125Q540.8137 340.20312 541.32935 340.64062Q542.01685 341.21875 542.345 342.125Q542.6887 343.01562 542.6887 344.15625Q542.6887 345.14062 542.45435 345.89062Q542.2356 346.64062 541.8762 347.14062Q541.51685 347.64062 541.07935 347.92188Q540.6575 348.20312 540.0637 348.35938Q539.47 348.5 538.6887 348.5L535.57935 348.5ZM536.72 347.48438L538.5481 347.48438Q539.4075 347.48438 539.89185 347.32812Q540.3762 347.17188 540.6575 346.875Q541.0637 346.48438 541.2825 345.79688Q541.51685 345.10938 541.51685 344.14062Q541.51685 342.79688 541.0637 342.07812Q540.6262 341.34375 540.0012 341.09375Q539.5325 340.92188 538.5325 340.92188L536.72 340.92188L536.72 347.48438ZM548.70435 346.5L549.7981 346.625Q549.5481 347.57812 548.845 348.10938Q548.14185 348.64062 547.0637 348.64062Q545.70435 348.64062 544.89185 347.79688Q544.095 346.95312 544.095 345.4375Q544.095 343.875 544.9075 343.01562Q545.72 342.14062 547.0012 342.14062Q548.2512 342.14062 549.0325 342.98438Q549.82935 343.82812 549.82935 345.375Q549.82935 345.46875 549.82935 345.65625L545.1887 345.65625Q545.2512 346.6875 545.76685 347.23438Q546.2825 347.76562 547.0637 347.76562Q547.64185 347.76562 548.0481 347.46875Q548.47 347.15625 548.70435 346.5ZM545.2512 344.79688L548.72 344.79688Q548.6575 344.0 548.32935 343.60938Q547.8137 343.0 547.01685 343.0Q546.2825 343.0 545.7825 343.48438Q545.2981 343.96875 545.2512 344.79688ZM551.45435 350.89062L551.45435 342.28125L552.4075 342.28125L552.4075 343.07812Q552.7512 342.60938 553.1731 342.375Q553.6106 342.14062 554.22 342.14062Q555.01685 342.14062 555.6262 342.54688Q556.2356 342.95312 556.5325 343.70312Q556.845 344.45312 556.845 345.34375Q556.845 346.29688 556.5012 347.0625Q556.1731 347.82812 555.51685 348.23438Q554.8606 348.64062 554.14185 348.64062Q553.6106 348.64062 553.1887 348.42188Q552.76685 348.1875 552.5012 347.85938L552.5012 350.89062L551.45435 350.89062ZM552.4075 345.42188Q552.4075 346.625 552.89185 347.20312Q553.3762 347.76562 554.0637 347.76562Q554.76685 347.76562 555.26685 347.17188Q555.76685 346.57812 555.76685 345.32812Q555.76685 344.14062 555.2825 343.5625Q554.7981 342.96875 554.1106 342.96875Q553.4387 342.96875 552.9231 343.59375Q552.4075 344.21875 552.4075 345.42188ZM560.7512 347.5625L560.9075 348.48438Q560.45435 348.57812 560.1106 348.57812Q559.5325 348.57812 559.22 348.40625Q558.9075 348.21875 558.76685 347.92188Q558.64185 347.625 558.64185 346.67188L558.64185 343.09375L557.8762 343.09375L557.8762 342.28125L558.64185 342.28125L558.64185 340.73438L559.6887 340.10938L559.6887 342.28125L560.7512 342.28125L560.7512 343.09375L559.6887 343.09375L559.6887 346.73438Q559.6887 347.1875 559.7356 347.3125Q559.7981 347.4375 559.9231 347.51562Q560.0481 347.59375 560.2825 347.59375Q560.47 347.59375 560.7512 347.5625ZM561.45435 348.5L561.45435 339.90625L562.5012 339.90625L562.5012 342.98438Q563.2356 342.14062 564.3606 342.14062Q565.0637 342.14062 565.5637 342.42188Q566.07935 342.6875 566.2981 343.17188Q566.51685 343.64062 566.51685 344.5625L566.51685 348.5L565.47 348.5L565.47 344.5625Q565.47 343.76562 565.1262 343.40625Q564.7825 343.04688 564.1575 343.04688Q563.6887 343.04688 563.26685 343.29688Q562.8606 343.53125 562.6731 343.95312Q562.5012 344.35938 562.5012 345.09375L562.5012 348.5L561.45435 348.5ZM571.0637 345.39062Q571.0637 343.65625 572.01685 342.82812Q572.8137 342.14062 573.97 342.14062Q575.2512 342.14062 576.0637 342.98438Q576.89185 343.8125 576.89185 345.29688Q576.89185 346.5 576.5325 347.1875Q576.1731 347.875 575.47 348.26562Q574.7825 348.64062 573.97 348.64062Q572.6731 348.64062 571.8606 347.8125Q571.0637 346.96875 571.0637 345.39062ZM572.14185 345.39062Q572.14185 346.57812 572.6575 347.17188Q573.1887 347.76562 573.97 347.76562Q574.76685 347.76562 575.2825 347.17188Q575.7981 346.57812 575.7981 345.35938Q575.7981 344.20312 575.26685 343.60938Q574.7512 343.01562 573.97 343.01562Q573.1887 343.01562 572.6575 343.60938Q572.14185 344.1875 572.14185 345.39062ZM578.70435 348.5L578.70435 343.09375L577.76685 343.09375L577.76685 342.28125L578.70435 342.28125L578.70435 341.60938Q578.70435 340.98438 578.8137 340.6875Q578.97 340.26562 579.345 340.01562Q579.7356 339.76562 580.4231 339.76562Q580.8762 339.76562 581.4075 339.875L581.2512 340.78125Q580.9231 340.73438 580.6262 340.73438Q580.14185 340.73438 579.9387 340.9375Q579.7512 341.14062 579.7512 341.70312L579.7512 342.28125L580.97 342.28125L580.97 343.09375L579.7512 343.09375L579.7512 348.5L578.70435 348.5ZM584.64185 348.5L584.64185 339.90625L590.4387 339.90625L590.4387 340.92188L585.7825 340.92188L585.7825 343.57812L589.8137 343.57812L589.8137 344.59375L585.7825 344.59375L585.7825 348.5L584.64185 348.5ZM591.45435 341.125L591.45435 339.90625L592.51685 339.90625L592.51685 341.125L591.45435 341.125ZM591.45435 348.5L591.45435 342.28125L592.51685 342.28125L592.51685 348.5L591.45435 348.5ZM598.70435 346.5L599.7981 346.625Q599.5481 347.57812 598.845 348.10938Q598.14185 348.64062 597.0637 348.64062Q595.70435 348.64062 594.89185 347.79688Q594.095 346.95312 594.095 345.4375Q594.095 343.875 594.9075 343.01562Q595.72 342.14062 597.0012 342.14062Q598.2512 342.14062 599.0325 342.98438Q599.82935 343.82812 599.82935 345.375Q599.82935 345.46875 599.82935 345.65625L595.1887 345.65625Q595.2512 346.6875 595.76685 347.23438Q596.2825 347.76562 597.0637 347.76562Q597.64185 347.76562 598.0481 347.46875Q598.47 347.15625 598.70435 346.5ZM595.2512 344.79688L598.72 344.79688Q598.6575 344.0 598.32935 343.60938Q597.8137 343.0 597.01685 343.0Q596.2825 343.0 595.7825 343.48438Q595.2981 343.96875 595.2512 344.79688ZM601.4231 348.5L601.4231 339.90625L602.4856 339.90625L602.4856 348.5L601.4231 348.5ZM608.4856 348.5L608.4856 347.71875Q607.89185 348.64062 606.7512 348.64062Q606.0012 348.64062 605.3762 348.23438Q604.7512 347.8125 604.4075 347.07812Q604.0637 346.34375 604.0637 345.39062Q604.0637 344.46875 604.3762 343.70312Q604.6887 342.9375 605.3137 342.54688Q605.9387 342.14062 606.70435 342.14062Q607.26685 342.14062 607.70435 342.375Q608.14185 342.60938 608.4231 342.98438L608.4231 339.90625L609.47 339.90625L609.47 348.5L608.4856 348.5ZM605.1575 345.39062Q605.1575 346.59375 605.6575 347.1875Q606.1575 347.76562 606.845 347.76562Q607.5325 347.76562 608.01685 347.20312Q608.5012 346.64062 608.5012 345.48438Q608.5012 344.20312 608.0012 343.60938Q607.51685 343.01562 606.7981 343.01562Q606.095 343.01562 605.6262 343.59375Q605.1575 344.15625 605.1575 345.39062Z" fill-rule="nonzero"/><path fill="#000000" d="M631.3979 348.5L631.3979 339.90625L632.5229 339.90625L632.5229 343.4375L636.99164 343.4375L636.99164 339.90625L638.13226 339.90625L638.13226 348.5L636.99164 348.5L636.99164 344.45312L632.5229 344.45312L632.5229 348.5L631.3979 348.5ZM639.8354 345.39062Q639.8354 343.65625 640.7885 342.82812Q641.5854 342.14062 642.74164 342.14062Q644.0229 342.14062 644.8354 342.98438Q645.6635 343.8125 645.6635 345.29688Q645.6635 346.5 645.30414 347.1875Q644.94476 347.875 644.24164 348.26562Q643.55414 348.64062 642.74164 348.64062Q641.44476 348.64062 640.63226 347.8125Q639.8354 346.96875 639.8354 345.39062ZM640.9135 345.39062Q640.9135 346.57812 641.42914 347.17188Q641.9604 347.76562 642.74164 347.76562Q643.5385 347.76562 644.05414 347.17188Q644.56976 346.57812 644.56976 345.35938Q644.56976 344.20312 644.0385 343.60938Q643.5229 343.01562 642.74164 343.01562Q641.9604 343.01562 641.42914 343.60938Q640.9135 344.1875 640.9135 345.39062ZM647.2104 348.5L647.2104 342.28125L648.1635 342.28125L648.1635 343.21875Q648.5229 342.5625 648.81976 342.35938Q649.13226 342.14062 649.50726 342.14062Q650.0385 342.14062 650.5854 342.46875L650.226 343.45312Q649.8354 343.21875 649.4604 343.21875Q649.101 343.21875 648.81976 343.4375Q648.55414 343.64062 648.44476 344.01562Q648.25726 344.57812 648.25726 345.23438L648.25726 348.5L647.2104 348.5ZM651.226 341.125L651.226 339.90625L652.2885 339.90625L652.2885 341.125L651.226 341.125ZM651.226 348.5L651.226 342.28125L652.2885 342.28125L652.2885 348.5L651.226 348.5ZM653.6635 348.5L653.6635 347.64062L657.63226 343.09375Q656.94476 343.125 656.42914 343.125L653.8979 343.125L653.8979 342.28125L658.99164 342.28125L658.99164 342.96875L655.61664 346.92188L654.9604 347.64062Q655.67914 347.59375 656.2885 347.59375L659.17914 347.59375L659.17914 348.5L653.6635 348.5ZM659.8354 345.39062Q659.8354 343.65625 660.7885 342.82812Q661.5854 342.14062 662.74164 342.14062Q664.0229 342.14062 664.8354 342.98438Q665.6635 343.8125 665.6635 345.29688Q665.6635 346.5 665.30414 347.1875Q664.94476 347.875 664.24164 348.26562Q663.55414 348.64062 662.74164 348.64062Q661.44476 348.64062 660.63226 347.8125Q659.8354 346.96875 659.8354 345.39062ZM660.9135 345.39062Q660.9135 346.57812 661.42914 347.17188Q661.9604 347.76562 662.74164 347.76562Q663.5385 347.76562 664.05414 347.17188Q664.56976 346.57812 664.56976 345.35938Q664.56976 344.20312 664.0385 343.60938Q663.5229 343.01562 662.74164 343.01562Q661.9604 343.01562 661.42914 343.60938Q660.9135 344.1875 660.9135 345.39062ZM667.226 348.5L667.226 342.28125L668.1635 342.28125L668.1635 343.15625Q668.851 342.14062 670.1479 342.14062Q670.7104 342.14062 671.17914 342.34375Q671.6635 342.54688 671.8979 342.875Q672.13226 343.20312 672.226 343.64062Q672.2729 343.9375 672.2729 344.67188L672.2729 348.5L671.226 348.5L671.226 344.71875Q671.226 344.0625 671.101 343.75Q670.976 343.4375 670.6635 343.25Q670.351 343.04688 669.92914 343.04688Q669.25726 343.04688 668.75726 343.48438Q668.2729 343.90625 668.2729 345.09375L668.2729 348.5L667.226 348.5ZM677.351 348.5L677.351 339.90625L680.31976 339.90625Q681.31976 339.90625 681.851 340.03125Q682.5854 340.20312 683.101 340.64062Q683.7885 341.21875 684.11664 342.125Q684.4604 343.01562 684.4604 344.15625Q684.4604 345.14062 684.226 345.89062Q684.00726 346.64062 683.6479 347.14062Q683.2885 347.64062 682.851 347.92188Q682.42914 348.20312 681.8354 348.35938Q681.24164 348.5 680.4604 348.5L677.351 348.5ZM678.49164 347.48438L680.31976 347.48438Q681.17914 347.48438 681.6635 347.32812Q682.1479 347.17188 682.42914 346.875Q682.8354 346.48438 683.05414 345.79688Q683.2885 345.10938 683.2885 344.14062Q683.2885 342.79688 682.8354 342.07812Q682.3979 341.34375 681.7729 341.09375Q681.30414 340.92188 680.30414 340.92188L678.49164 340.92188L678.49164 347.48438ZM690.476 346.5L691.56976 346.625Q691.31976 347.57812 690.61664 348.10938Q689.9135 348.64062 688.8354 348.64062Q687.476 348.64062 686.6635 347.79688Q685.86664 346.95312 685.86664 345.4375Q685.86664 343.875 686.67914 343.01562Q687.49164 342.14062 688.7729 342.14062Q690.0229 342.14062 690.80414 342.98438Q691.601 343.82812 691.601 345.375Q691.601 345.46875 691.601 345.65625L686.9604 345.65625Q687.0229 346.6875 687.5385 347.23438Q688.05414 347.76562 688.8354 347.76562Q689.4135 347.76562 689.81976 347.46875Q690.24164 347.15625 690.476 346.5ZM687.0229 344.79688L690.49164 344.79688Q690.42914 344.0 690.101 343.60938Q689.5854 343.0 688.7885 343.0Q688.05414 343.0 687.55414 343.48438Q687.06976 343.96875 687.0229 344.79688ZM695.5229 347.5625L695.67914 348.48438Q695.226 348.57812 694.88226 348.57812Q694.30414 348.57812 693.99164 348.40625Q693.67914 348.21875 693.5385 347.92188Q693.4135 347.625 693.4135 346.67188L693.4135 343.09375L692.6479 343.09375L692.6479 342.28125L693.4135 342.28125L693.4135 340.73438L694.4604 340.10938L694.4604 342.28125L695.5229 342.28125L695.5229 343.09375L694.4604 343.09375L694.4604 346.73438Q694.4604 347.1875 694.50726 347.3125Q694.56976 347.4375 694.69476 347.51562Q694.81976 347.59375 695.05414 347.59375Q695.24164 347.59375 695.5229 347.5625ZM700.476 346.5L701.56976 346.625Q701.31976 347.57812 700.61664 348.10938Q699.9135 348.64062 698.8354 348.64062Q697.476 348.64062 696.6635 347.79688Q695.86664 346.95312 695.86664 345.4375Q695.86664 343.875 696.67914 343.01562Q697.49164 342.14062 698.7729 342.14062Q700.0229 342.14062 700.80414 342.98438Q701.601 343.82812 701.601 345.375Q701.601 345.46875 701.601 345.65625L696.9604 345.65625Q697.0229 346.6875 697.5385 347.23438Q698.05414 347.76562 698.8354 347.76562Q699.4135 347.76562 699.81976 347.46875Q700.24164 347.15625 700.476 346.5ZM697.0229 344.79688L700.49164 344.79688Q700.42914 344.0 700.101 343.60938Q699.5854 343.0 698.7885 343.0Q698.05414 343.0 697.55414 343.48438Q697.06976 343.96875 697.0229 344.79688ZM707.2885 346.21875L708.31976 346.35938Q708.1479 347.42188 707.44476 348.03125Q706.74164 348.64062 705.726 348.64062Q704.44476 348.64062 703.6635 347.8125Q702.8979 346.96875 702.8979 345.40625Q702.8979 344.40625 703.226 343.65625Q703.56976 342.89062 704.24164 342.51562Q704.92914 342.14062 705.74164 342.14062Q706.74164 342.14062 707.38226 342.65625Q708.0385 343.15625 708.226 344.10938L707.19476 344.26562Q707.05414 343.64062 706.67914 343.32812Q706.30414 343.0 705.7729 343.0Q704.976 343.0 704.476 343.57812Q703.976 344.14062 703.976 345.375Q703.976 346.64062 704.4604 347.20312Q704.94476 347.76562 705.7104 347.76562Q706.3354 347.76562 706.74164 347.39062Q707.1635 347.01562 707.2885 346.21875ZM711.5229 347.5625L711.67914 348.48438Q711.226 348.57812 710.88226 348.57812Q710.30414 348.57812 709.99164 348.40625Q709.67914 348.21875 709.5385 347.92188Q709.4135 347.625 709.4135 346.67188L709.4135 343.09375L708.6479 343.09375L708.6479 342.28125L709.4135 342.28125L709.4135 340.73438L710.4604 340.10938L710.4604 342.28125L711.5229 342.28125L711.5229 343.09375L710.4604 343.09375L710.4604 346.73438Q710.4604 347.1875 710.50726 347.3125Q710.56976 347.4375 710.69476 347.51562Q710.81976 347.59375 711.05414 347.59375Q711.24164 347.59375 711.5229 347.5625ZM712.226 341.125L712.226 339.90625L713.2885 339.90625L713.2885 341.125L712.226 341.125ZM712.226 348.5L712.226 342.28125L713.2885 342.28125L713.2885 348.5L712.226 348.5ZM714.8354 345.39062Q714.8354 343.65625 715.7885 342.82812Q716.5854 342.14062 717.74164 342.14062Q719.0229 342.14062 719.8354 342.98438Q720.6635 343.8125 720.6635 345.29688Q720.6635 346.5 720.30414 347.1875Q719.94476 347.875 719.24164 348.26562Q718.55414 348.64062 717.74164 348.64062Q716.44476 348.64062 715.63226 347.8125Q714.8354 346.96875 714.8354 345.39062ZM715.9135 345.39062Q715.9135 346.57812 716.42914 347.17188Q716.9604 347.76562 717.74164 347.76562Q718.5385 347.76562 719.05414 347.17188Q719.56976 346.57812 719.56976 345.35938Q719.56976 344.20312 719.0385 343.60938Q718.5229 343.01562 717.74164 343.01562Q716.9604 343.01562 716.42914 343.60938Q715.9135 344.1875 715.9135 345.39062ZM722.226 348.5L722.226 342.28125L723.1635 342.28125L723.1635 343.15625Q723.851 342.14062 725.1479 342.14062Q725.7104 342.14062 726.17914 342.34375Q726.6635 342.54688 726.8979 342.875Q727.13226 343.20312 727.226 343.64062Q727.2729 343.9375 727.2729 344.67188L727.2729 348.5L726.226 348.5L726.226 344.71875Q726.226 344.0625 726.101 343.75Q725.976 343.4375 725.6635 343.25Q725.351 343.04688 724.92914 343.04688Q724.25726 343.04688 723.75726 343.48438Q723.2729 343.90625 723.2729 345.09375L723.2729 348.5L722.226 348.5Z" fill-rule="nonzero"/><path fill="#4285f4" d="M314.0 56.833332C314.0 56.281048 314.44772 55.833332 315.0 55.833332L325.0 55.833332C325.55228 55.833332 326.0 56.281048 326.0 56.833332L326.0 66.833336C326.0 67.38562 325.55228 67.833336 325.0 67.833336L315.0 67.833336C314.44772 67.833336 314.0 67.38562 314.0 66.833336Z" fill-rule="nonzero"/><path fill="#1a1a1a" d="M334.23438 65.833336L334.23438 64.770836L338.64062 59.270836Q339.10938 58.69271 339.53125 58.25521L334.73438 58.25521L334.73438 57.239586L340.89062 57.239586L340.89062 58.25521L336.0625 64.208336L335.54688 64.81771L341.03125 64.81771L341.03125 65.833336L334.23438 65.833336ZM341.875 65.833336L341.875 57.239586L343.01562 57.239586L343.01562 64.81771L347.25 64.81771L347.25 65.833336L341.875 65.833336ZM354.5625 57.239586L355.70312 57.239586L355.70312 62.208336Q355.70312 63.50521 355.40625 64.270836Q355.10938 65.020836 354.34375 65.50521Q353.57812 65.97396 352.34375 65.97396Q351.14062 65.97396 350.35938 65.56771Q349.59375 65.145836 349.26562 64.364586Q348.9375 63.56771 348.9375 62.208336L348.9375 57.239586L350.07812 57.239586L350.07812 62.19271Q350.07812 63.31771 350.28125 63.84896Q350.5 64.38021 351.0 64.677086Q351.51562 64.958336 352.25 64.958336Q353.5 64.958336 354.03125 64.395836Q354.5625 63.81771 354.5625 62.19271L354.5625 57.239586ZM357.92188 65.833336L357.92188 57.239586L360.89062 57.239586Q361.89062 57.239586 362.42188 57.364586Q363.15625 57.53646 363.67188 57.97396Q364.35938 58.552086 364.6875 59.458336Q365.03125 60.34896 365.03125 61.489586Q365.03125 62.47396 364.79688 63.22396Q364.57812 63.97396 364.21875 64.47396Q363.85938 64.97396 363.42188 65.25521Q363.0 65.53646 362.40625 65.69271Q361.8125 65.833336 361.03125 65.833336L357.92188 65.833336ZM359.0625 64.81771L360.89062 64.81771Q361.75 64.81771 362.23438 64.66146Q362.71875 64.50521 363.0 64.208336Q363.40625 63.81771 363.625 63.13021Q363.85938 62.44271 363.85938 61.47396Q363.85938 60.13021 363.40625 59.41146Q362.96875 58.677086 362.34375 58.427086Q361.875 58.25521 360.875 58.25521L359.0625 58.25521L359.0625 64.81771ZM365.98438 65.833336L369.28125 57.239586L370.5 57.239586L374.01562 65.833336L372.73438 65.833336L371.71875 63.22396L368.14062 63.22396L367.1875 65.833336L365.98438 65.833336ZM368.46875 62.302086L371.375 62.302086L370.48438 59.927086Q370.0625 58.84896 369.875 58.145836Q369.70312 58.97396 369.40625 59.78646L368.46875 62.302086Z" fill-rule="nonzero"/><path fill="#ea4335" d="M390.0 56.833332C390.0 56.281048 390.44772 55.833332 391.0 55.833332L401.0 55.833332C401.55228 55.833332 402.0 56.281048 402.0 56.833332L402.0 66.833336C402.0 67.38562 401.55228 67.833336 401.0 67.833336L391.0 67.833336C390.44772 67.833336 390.0 67.38562 390.0 66.833336Z" fill-rule="nonzero"/><path fill="#1a1a1a" d="M410.57812 61.645836Q410.57812 59.50521 411.71875 58.302086Q412.875 57.083336 414.6875 57.083336Q415.89062 57.083336 416.84375 57.66146Q417.79688 58.22396 418.29688 59.239586Q418.79688 60.25521 418.79688 61.552086Q418.79688 62.84896 418.26562 63.88021Q417.73438 64.91146 416.76562 65.44271Q415.8125 65.97396 414.6875 65.97396Q413.46875 65.97396 412.51562 65.395836Q411.5625 64.802086 411.0625 63.802086Q410.57812 62.78646 410.57812 61.645836ZM411.75 61.66146Q411.75 63.22396 412.57812 64.114586Q413.42188 65.00521 414.6875 65.00521Q415.96875 65.00521 416.79688 64.114586Q417.625 63.208336 417.625 61.53646Q417.625 60.489586 417.26562 59.708336Q416.92188 58.927086 416.23438 58.50521Q415.54688 58.06771 414.70312 58.06771Q413.5 58.06771 412.625 58.895836Q411.75 59.72396 411.75 61.66146ZM419.79688 68.22396L419.79688 59.614586L420.75 59.614586L420.75 60.41146Q421.09375 59.94271 421.51562 59.708336Q421.95312 59.47396 422.5625 59.47396Q423.35938 59.47396 423.96875 59.88021Q424.57812 60.28646 424.875 61.03646Q425.1875 61.78646 425.1875 62.677086Q425.1875 63.63021 424.84375 64.395836Q424.51562 65.16146 423.85938 65.56771Q423.20312 65.97396 422.48438 65.97396Q421.95312 65.97396 421.53125 65.75521Q421.10938 65.520836 420.84375 65.19271L420.84375 68.22396L419.79688 68.22396ZM420.75 62.75521Q420.75 63.958336 421.23438 64.53646Q421.71875 65.09896 422.40625 65.09896Q423.10938 65.09896 423.60938 64.50521Q424.10938 63.91146 424.10938 62.66146Q424.10938 61.47396 423.625 60.895836Q423.14062 60.302086 422.45312 60.302086Q421.78125 60.302086 421.26562 60.927086Q420.75 61.552086 420.75 62.75521ZM431.04688 63.833336L432.14062 63.958336Q431.89062 64.91146 431.1875 65.44271Q430.48438 65.97396 429.40625 65.97396Q428.04688 65.97396 427.23438 65.13021Q426.4375 64.28646 426.4375 62.770836Q426.4375 61.208336 427.25 60.34896Q428.0625 59.47396 429.34375 59.47396Q430.59375 59.47396 431.375 60.31771Q432.17188 61.16146 432.17188 62.708336Q432.17188 62.802086 432.17188 62.989586L427.53125 62.989586Q427.59375 64.020836 428.10938 64.56771Q428.625 65.09896 429.40625 65.09896Q429.98438 65.09896 430.39062 64.802086Q430.8125 64.489586 431.04688 63.833336ZM427.59375 62.13021L431.0625 62.13021Q431.0 61.333336 430.67188 60.94271Q430.15625 60.333336 429.35938 60.333336Q428.625 60.333336 428.125 60.81771Q427.64062 61.302086 427.59375 62.13021ZM433.79688 65.833336L433.79688 59.614586L434.73438 59.614586L434.73438 60.489586Q435.42188 59.47396 436.71875 59.47396Q437.28125 59.47396 437.75 59.677086Q438.23438 59.88021 438.46875 60.208336Q438.70312 60.53646 438.79688 60.97396Q438.84375 61.270836 438.84375 62.00521L438.84375 65.833336L437.79688 65.833336L437.79688 62.052086Q437.79688 61.395836 437.67188 61.083336Q437.54688 60.770836 437.23438 60.583336Q436.92188 60.38021 436.5 60.38021Q435.82812 60.38021 435.32812 60.81771Q434.84375 61.239586 434.84375 62.427086L434.84375 65.833336L433.79688 65.833336ZM447.0625 62.81771L448.1875 63.114586Q447.82812 64.50521 446.90625 65.239586Q445.98438 65.97396 444.64062 65.97396Q443.25 65.97396 442.375 65.41146Q441.5 64.84896 441.04688 63.78646Q440.59375 62.708336 440.59375 61.47396Q440.59375 60.13021 441.10938 59.13021Q441.625 58.13021 442.5625 57.614586Q443.51562 57.09896 444.65625 57.09896Q445.9375 57.09896 446.8125 57.75521Q447.70312 58.41146 448.04688 59.59896L446.92188 59.864586Q446.625 58.927086 446.04688 58.50521Q445.48438 58.06771 444.625 58.06771Q443.64062 58.06771 442.96875 58.552086Q442.3125 59.020836 442.03125 59.81771Q441.76562 60.614586 441.76562 61.47396Q441.76562 62.56771 442.07812 63.38021Q442.40625 64.19271 443.07812 64.59896Q443.75 65.00521 444.54688 65.00521Q445.5 65.00521 446.15625 64.458336Q446.82812 63.91146 447.0625 62.81771ZM449.875 65.833336L449.875 57.239586L451.01562 57.239586L451.01562 64.81771L455.25 64.81771L455.25 65.833336L449.875 65.833336Z" fill-rule="nonzero"/><path fill="#757575" d="M26.75 31.890625L26.75 30.203125L32.8125 30.1875L32.8125 35.5Q31.40625 36.625 29.921875 37.1875Q28.4375 37.75 26.875 37.75Q24.765625 37.75 23.046875 36.84375Q21.328125 35.9375 20.4375 34.234375Q19.5625 32.515625 19.5625 30.40625Q19.5625 28.3125 20.4375 26.515625Q21.3125 24.703125 22.953125 23.828125Q24.59375 22.9375 26.734375 22.9375Q28.28125 22.9375 29.53125 23.4375Q30.796875 23.9375 31.5 24.84375Q32.21875 25.734375 32.59375 27.1875L30.890625 27.65625Q30.5625 26.5625 30.078125 25.9375Q29.609375 25.3125 28.71875 24.9375Q27.828125 24.5625 26.75 24.5625Q25.4375 24.5625 24.484375 24.953125Q23.546875 25.34375 22.96875 26.0Q22.390625 26.640625 22.0625 27.40625Q21.515625 28.734375 21.515625 30.296875Q21.515625 32.203125 22.171875 33.5Q22.84375 34.78125 24.09375 35.40625Q25.359375 36.03125 26.765625 36.03125Q28.0 36.03125 29.171875 35.5625Q30.34375 35.09375 30.953125 34.546875L30.953125 31.890625L26.75 31.890625ZM42.921875 34.15625L44.734375 34.390625Q44.3125 35.96875 43.140625 36.859375Q41.984375 37.734375 40.171875 37.734375Q37.90625 37.734375 36.5625 36.34375Q35.234375 34.9375 35.234375 32.40625Q35.234375 29.78125 36.578125 28.34375Q37.921875 26.890625 40.078125 26.890625Q42.15625 26.890625 43.46875 28.3125Q44.796875 29.71875 44.796875 32.296875Q44.796875 32.453125 44.78125 32.765625L37.046875 32.765625Q37.140625 34.46875 38.015625 35.375Q38.890625 36.28125 40.1875 36.28125Q41.15625 36.28125 41.828125 35.78125Q42.515625 35.265625 42.921875 34.15625ZM37.140625 31.3125L42.9375 31.3125Q42.828125 30.015625 42.28125 29.359375Q41.4375 28.34375 40.09375 28.34375Q38.890625 28.34375 38.0625 29.15625Q37.234375 29.953125 37.140625 31.3125ZM53.921875 34.15625L55.734375 34.390625Q55.3125 35.96875 54.140625 36.859375Q52.984375 37.734375 51.171875 37.734375Q48.90625 37.734375 47.5625 36.34375Q46.234375 34.9375 46.234375 32.40625Q46.234375 29.78125 47.578125 28.34375Q48.921875 26.890625 51.078125 26.890625Q53.15625 26.890625 54.46875 28.3125Q55.796875 29.71875 55.796875 32.296875Q55.796875 32.453125 55.78125 32.765625L48.046875 32.765625Q48.140625 34.46875 49.015625 35.375Q49.890625 36.28125 51.1875 36.28125Q52.15625 36.28125 52.828125 35.78125Q53.515625 35.265625 53.921875 34.15625ZM48.140625 31.3125L53.9375 31.3125Q53.828125 30.015625 53.28125 29.359375Q52.4375 28.34375 51.09375 28.34375Q49.890625 28.34375 49.0625 29.15625Q48.234375 29.953125 48.140625 31.3125ZM57.828125 37.5L57.828125 23.1875L59.59375 23.1875L59.59375 31.34375L63.75 27.125L66.015625 27.125L62.0625 30.96875L66.421875 37.5L64.25 37.5L60.828125 32.203125L59.59375 33.390625L59.59375 37.5L57.828125 37.5ZM67.96875 37.5L67.96875 23.1875L73.34375 23.1875Q74.984375 23.1875 75.96875 23.625Q76.953125 24.046875 77.515625 24.953125Q78.078125 25.859375 78.078125 26.84375Q78.078125 27.765625 77.578125 28.578125Q77.09375 29.390625 76.078125 29.875Q77.375 30.265625 78.078125 31.1875Q78.78125 32.09375 78.78125 33.34375Q78.78125 34.359375 78.34375 35.21875Q77.921875 36.078125 77.296875 36.546875Q76.671875 37.015625 75.734375 37.265625Q74.796875 37.5 73.421875 37.5L67.96875 37.5ZM69.859375 29.203125L72.953125 29.203125Q74.21875 29.203125 74.765625 29.03125Q75.484375 28.8125 75.84375 28.328125Q76.21875 27.828125 76.21875 27.0625Q76.21875 26.359375 75.875 25.8125Q75.53125 25.265625 74.890625 25.078125Q74.265625 24.875 72.71875 24.875L69.859375 24.875L69.859375 29.203125ZM69.859375 35.8125L73.421875 35.8125Q74.34375 35.8125 74.71875 35.734375Q75.375 35.625 75.8125 35.359375Q76.25 35.078125 76.53125 34.5625Q76.8125 34.03125 76.8125 33.34375Q76.8125 32.546875 76.40625 31.953125Q76.0 31.359375 75.265625 31.125Q74.53125 30.890625 73.171875 30.890625L69.859375 30.890625L69.859375 35.8125ZM87.921875 34.15625L89.734375 34.390625Q89.3125 35.96875 88.140625 36.859375Q86.984375 37.734375 85.171875 37.734375Q82.90625 37.734375 81.5625 36.34375Q80.234375 34.9375 80.234375 32.40625Q80.234375 29.78125 81.578125 28.34375Q82.921875 26.890625 85.078125 26.890625Q87.15625 26.890625 88.46875 28.3125Q89.796875 29.71875 89.796875 32.296875Q89.796875 32.453125 89.78125 32.765625L82.046875 32.765625Q82.140625 34.46875 83.015625 35.375Q83.890625 36.28125 85.1875 36.28125Q86.15625 36.28125 86.828125 35.78125Q87.515625 35.265625 87.921875 34.15625ZM82.140625 31.3125L87.9375 31.3125Q87.828125 30.015625 87.28125 29.359375Q86.4375 28.34375 85.09375 28.34375Q83.890625 28.34375 83.0625 29.15625Q82.234375 29.953125 82.140625 31.3125ZM91.8125 37.5L91.8125 27.125L93.40625 27.125L93.40625 28.609375Q94.546875 26.890625 96.703125 26.890625Q97.640625 26.890625 98.421875 27.234375Q99.21875 27.5625 99.609375 28.109375Q100.0 28.65625 100.15625 29.40625Q100.25 29.90625 100.25 31.125L100.25 37.5L98.484375 37.5L98.484375 31.1875Q98.484375 30.109375 98.28125 29.578125Q98.078125 29.046875 97.546875 28.734375Q97.03125 28.421875 96.328125 28.421875Q95.203125 28.421875 94.390625 29.140625Q93.578125 29.84375 93.578125 31.828125L93.578125 37.5L91.8125 37.5ZM109.59375 33.703125L111.3125 33.921875Q111.03125 35.71875 109.859375 36.734375Q108.703125 37.734375 107.0 37.734375Q104.875 37.734375 103.578125 36.34375Q102.28125 34.953125 102.28125 32.359375Q102.28125 30.671875 102.828125 29.421875Q103.390625 28.15625 104.53125 27.53125Q105.671875 26.890625 107.015625 26.890625Q108.703125 26.890625 109.765625 27.75Q110.84375 28.609375 111.15625 30.171875L109.4375 30.4375Q109.203125 29.390625 108.578125 28.875Q107.953125 28.34375 107.078125 28.34375Q105.75 28.34375 104.921875 29.296875Q104.09375 30.25 104.09375 32.296875Q104.09375 34.390625 104.890625 35.34375Q105.6875 36.28125 106.984375 36.28125Q108.015625 36.28125 108.703125 35.65625Q109.40625 35.015625 109.59375 33.703125ZM112.8125 37.5L112.8125 23.1875L114.578125 23.1875L114.578125 28.3125Q115.8125 26.890625 117.6875 26.890625Q118.828125 26.890625 119.671875 27.34375Q120.53125 27.796875 120.890625 28.609375Q121.265625 29.40625 121.265625 30.921875L121.265625 37.5L119.515625 37.5L119.515625 30.921875Q119.515625 29.609375 118.9375 29.015625Q118.359375 28.40625 117.328125 28.40625Q116.546875 28.40625 115.84375 28.8125Q115.15625 29.21875 114.859375 29.921875Q114.578125 30.609375 114.578125 31.828125L114.578125 37.5L112.8125 37.5ZM129.32812 33.75L131.17188 33.59375Q131.375 34.9375 132.125 35.625Q132.875 36.296875 133.9375 36.296875Q135.20312 36.296875 136.07812 35.34375Q136.95312 34.390625 136.95312 32.796875Q136.95312 31.296875 136.10938 30.4375Q135.26562 29.5625 133.90625 29.5625Q133.04688 29.5625 132.35938 29.953125Q131.6875 30.328125 131.29688 30.953125L129.64062 30.734375L131.03125 23.375L138.15625 23.375L138.15625 25.0625L132.4375 25.0625L131.67188 28.90625Q132.95312 28.0 134.375 28.0Q136.25 28.0 137.53125 29.3125Q138.82812 30.609375 138.82812 32.640625Q138.82812 34.59375 137.6875 36.0Q136.3125 37.75 133.9375 37.75Q131.98438 37.75 130.73438 36.65625Q129.5 35.5625 129.32812 33.75ZM141.3125 37.5L141.3125 35.5L143.3125 35.5L143.3125 37.5L141.3125 37.5ZM155.5625 35.8125L155.5625 37.5L146.10938 37.5Q146.09375 36.859375 146.3125 36.28125Q146.67188 35.3125 147.46875 34.375Q148.26562 33.4375 149.76562 32.203125Q152.10938 30.296875 152.92188 29.1875Q153.75 28.0625 153.75 27.0625Q153.75 26.015625 153.0 25.296875Q152.25 24.578125 151.04688 24.578125Q149.78125 24.578125 149.01562 25.34375Q148.25 26.109375 148.25 27.453125L146.4375 27.265625Q146.625 25.25 147.82812 24.1875Q149.04688 23.125 151.09375 23.125Q153.14062 23.125 154.34375 24.265625Q155.54688 25.40625 155.54688 27.09375Q155.54688 27.953125 155.1875 28.796875Q154.84375 29.625 154.03125 30.546875Q153.21875 31.453125 151.32812 33.0625Q149.73438 34.390625 149.28125 34.859375Q148.84375 35.328125 148.54688 35.8125L155.5625 35.8125ZM158.3125 37.5L158.3125 35.5L160.3125 35.5L160.3125 37.5L158.3125 37.5ZM163.34375 33.71875L165.09375 33.484375Q165.40625 34.984375 166.125 35.640625Q166.85938 36.296875 167.90625 36.296875Q169.14062 36.296875 169.98438 35.4375Q170.84375 34.578125 170.84375 33.3125Q170.84375 32.09375 170.04688 31.3125Q169.26562 30.53125 168.04688 30.53125Q167.54688 30.53125 166.8125 30.71875L167.0 29.171875Q167.17188 29.203125 167.28125 29.203125Q168.40625 29.203125 169.29688 28.625Q170.20312 28.03125 170.20312 26.8125Q170.20312 25.84375 169.54688 25.203125Q168.89062 24.5625 167.85938 24.5625Q166.84375 24.5625 166.15625 25.21875Q165.46875 25.859375 165.28125 27.140625L163.51562 26.828125Q163.84375 25.0625 164.98438 24.09375Q166.125 23.125 167.82812 23.125Q169.0 23.125 169.98438 23.625Q170.96875 24.125 171.48438 25.0Q172.01562 25.875 172.01562 26.84375Q172.01562 27.765625 171.51562 28.53125Q171.01562 29.296875 170.04688 29.75Q171.3125 30.03125 172.01562 30.96875Q172.71875 31.890625 172.71875 33.265625Q172.71875 35.140625 171.34375 36.453125Q169.98438 37.75 167.89062 37.75Q166.0 37.75 164.75 36.625Q163.51562 35.5 163.34375 33.71875ZM180.14062 33.203125L180.14062 31.4375L185.53125 31.4375L185.53125 33.203125L180.14062 33.203125ZM193.82812 25.203125L193.82812 23.1875L195.59375 23.1875L195.59375 25.203125L193.82812 25.203125ZM193.82812 37.5L193.82812 27.125L195.59375 27.125L195.59375 37.5L193.82812 37.5ZM197.8125 37.5L197.8125 27.125L199.40625 27.125L199.40625 28.609375Q200.54688 26.890625 202.70312 26.890625Q203.64062 26.890625 204.42188 27.234375Q205.21875 27.5625 205.60938 28.109375Q206.0 28.65625 206.15625 29.40625Q206.25 29.90625 206.25 31.125L206.25 37.5L204.48438 37.5L204.48438 31.1875Q204.48438 30.109375 204.28125 29.578125Q204.07812 29.046875 203.54688 28.734375Q203.03125 28.421875 202.32812 28.421875Q201.20312 28.421875 200.39062 29.140625Q199.57812 29.84375 199.57812 31.828125L199.57812 37.5L197.8125 37.5ZM215.54688 37.5L215.54688 36.1875Q214.5625 37.734375 212.64062 37.734375Q211.40625 37.734375 210.35938 37.046875Q209.32812 36.359375 208.75 35.140625Q208.1875 33.921875 208.1875 32.328125Q208.1875 30.765625 208.70312 29.5Q209.21875 28.234375 210.25 27.5625Q211.29688 26.890625 212.5625 26.890625Q213.5 26.890625 214.23438 27.296875Q214.96875 27.6875 215.4375 28.3125L215.4375 23.1875L217.17188 23.1875L217.17188 37.5L215.54688 37.5ZM209.98438 32.328125Q209.98438 34.3125 210.82812 35.296875Q211.67188 36.28125 212.8125 36.28125Q213.96875 36.28125 214.76562 35.34375Q215.57812 34.40625 215.57812 32.46875Q215.57812 30.34375 214.75 29.34375Q213.9375 28.34375 212.73438 28.34375Q211.5625 28.34375 210.76562 29.3125Q209.98438 30.265625 209.98438 32.328125ZM219.82812 25.203125L219.82812 23.1875L221.59375 23.1875L221.59375 25.203125L219.82812 25.203125ZM219.82812 37.5L219.82812 27.125L221.59375 27.125L221.59375 37.5L219.82812 37.5ZM226.70312 37.5L222.75 27.125L224.60938 27.125L226.84375 33.34375Q227.20312 34.34375 227.5 35.421875Q227.73438 34.609375 228.15625 33.453125L230.45312 27.125L232.26562 27.125L228.34375 37.5L226.70312 37.5ZM233.82812 25.203125L233.82812 23.1875L235.59375 23.1875L235.59375 25.203125L233.82812 25.203125ZM233.82812 37.5L233.82812 27.125L235.59375 27.125L235.59375 37.5L233.82812 37.5ZM244.54688 37.5L244.54688 36.1875Q243.5625 37.734375 241.64062 37.734375Q240.40625 37.734375 239.35938 37.046875Q238.32812 36.359375 237.75 35.140625Q237.1875 33.921875 237.1875 32.328125Q237.1875 30.765625 237.70312 29.5Q238.21875 28.234375 239.25 27.5625Q240.29688 26.890625 241.5625 26.890625Q242.5 26.890625 243.23438 27.296875Q243.96875 27.6875 244.4375 28.3125L244.4375 23.1875L246.17188 23.1875L246.17188 37.5L244.54688 37.5ZM238.98438 32.328125Q238.98438 34.3125 239.82812 35.296875Q240.67188 36.28125 241.8125 36.28125Q242.96875 36.28125 243.76562 35.34375Q244.57812 34.40625 244.57812 32.46875Q244.57812 30.34375 243.75 29.34375Q242.9375 28.34375 241.73438 28.34375Q240.5625 28.34375 239.76562 29.3125Q238.98438 30.265625 238.98438 32.328125ZM255.60938 37.5L255.60938 35.96875Q254.40625 37.734375 252.32812 37.734375Q251.40625 37.734375 250.60938 37.390625Q249.8125 37.03125 249.42188 36.5Q249.04688 35.96875 248.89062 35.1875Q248.78125 34.671875 248.78125 33.546875L248.78125 27.125L250.53125 27.125L250.53125 32.875Q250.53125 34.25 250.64062 34.734375Q250.8125 35.421875 251.34375 35.828125Q251.89062 36.21875 252.67188 36.21875Q253.46875 36.21875 254.15625 35.8125Q254.85938 35.40625 255.14062 34.71875Q255.4375 34.015625 255.4375 32.6875L255.4375 27.125L257.1875 27.125L257.1875 37.5L255.60938 37.5ZM266.59375 36.21875Q265.60938 37.046875 264.70312 37.390625Q263.79688 37.734375 262.76562 37.734375Q261.0625 37.734375 260.14062 36.90625Q259.21875 36.0625 259.21875 34.765625Q259.21875 34.0 259.5625 33.375Q259.92188 32.75 260.48438 32.375Q261.04688 31.984375 261.75 31.78125Q262.26562 31.65625 263.3125 31.515625Q265.4375 31.265625 266.4375 30.921875Q266.45312 30.5625 266.45312 30.453125Q266.45312 29.390625 265.95312 28.9375Q265.28125 28.34375 263.95312 28.34375Q262.70312 28.34375 262.10938 28.78125Q261.53125 29.21875 261.25 30.328125L259.53125 30.09375Q259.76562 28.984375 260.29688 28.3125Q260.82812 27.625 261.84375 27.265625Q262.85938 26.890625 264.20312 26.890625Q265.53125 26.890625 266.35938 27.203125Q267.1875 27.515625 267.57812 28.0Q267.96875 28.46875 268.125 29.1875Q268.21875 29.640625 268.21875 30.8125L268.21875 33.15625Q268.21875 35.609375 268.32812 36.265625Q268.4375 36.90625 268.78125 37.5L266.9375 37.5Q266.67188 36.953125 266.59375 36.21875ZM266.4375 32.296875Q265.48438 32.6875 263.5625 32.953125Q262.48438 33.109375 262.03125 33.3125Q261.59375 33.5 261.34375 33.875Q261.09375 34.25 261.09375 34.71875Q261.09375 35.421875 261.625 35.890625Q262.15625 36.359375 263.1875 36.359375Q264.20312 36.359375 264.98438 35.921875Q265.78125 35.46875 266.15625 34.703125Q266.4375 34.09375 266.4375 32.9375L266.4375 32.296875ZM270.78125 37.5L270.78125 23.1875L272.53125 23.1875L272.53125 37.5L270.78125 37.5ZM282.4375 37.5L280.8125 37.5L280.8125 23.1875L282.5625 23.1875L282.5625 28.296875Q283.6875 26.890625 285.40625 26.890625Q286.35938 26.890625 287.21875 27.28125Q288.07812 27.671875 288.625 28.375Q289.17188 29.0625 289.48438 30.046875Q289.79688 31.03125 289.79688 32.15625Q289.79688 34.828125 288.48438 36.28125Q287.17188 37.734375 285.32812 37.734375Q283.48438 37.734375 282.4375 36.203125L282.4375 37.5ZM282.42188 32.234375Q282.42188 34.09375 282.92188 34.9375Q283.76562 36.28125 285.17188 36.28125Q286.32812 36.28125 287.15625 35.28125Q288.0 34.28125 288.0 32.296875Q288.0 30.265625 287.1875 29.3125Q286.39062 28.34375 285.25 28.34375Q284.09375 28.34375 283.25 29.34375Q282.42188 30.34375 282.42188 32.234375ZM298.92188 34.15625L300.73438 34.390625Q300.3125 35.96875 299.14062 36.859375Q297.98438 37.734375 296.17188 37.734375Q293.90625 37.734375 292.5625 36.34375Q291.23438 34.9375 291.23438 32.40625Q291.23438 29.78125 292.57812 28.34375Q293.92188 26.890625 296.07812 26.890625Q298.15625 26.890625 299.46875 28.3125Q300.79688 29.71875 300.79688 32.296875Q300.79688 32.453125 300.78125 32.765625L293.04688 32.765625Q293.14062 34.46875 294.01562 35.375Q294.89062 36.28125 296.1875 36.28125Q297.15625 36.28125 297.82812 35.78125Q298.51562 35.265625 298.92188 34.15625ZM293.14062 31.3125L298.9375 31.3125Q298.82812 30.015625 298.28125 29.359375Q297.4375 28.34375 296.09375 28.34375Q294.89062 28.34375 294.0625 29.15625Q293.23438 29.953125 293.14062 31.3125ZM302.8125 37.5L302.8125 27.125L304.40625 27.125L304.40625 28.609375Q305.54688 26.890625 307.70312 26.890625Q308.64062 26.890625 309.42188 27.234375Q310.21875 27.5625 310.60938 28.109375Q311.0 28.65625 311.15625 29.40625Q311.25 29.90625 311.25 31.125L311.25 37.5L309.48438 37.5L309.48438 31.1875Q309.48438 30.109375 309.28125 29.578125Q309.07812 29.046875 308.54688 28.734375Q308.03125 28.421875 307.32812 28.421875Q306.20312 28.421875 305.39062 29.140625Q304.57812 29.84375 304.57812 31.828125L304.57812 37.5L302.8125 37.5ZM320.59375 33.703125L322.3125 33.921875Q322.03125 35.71875 320.85938 36.734375Q319.70312 37.734375 318.0 37.734375Q315.875 37.734375 314.57812 36.34375Q313.28125 34.953125 313.28125 32.359375Q313.28125 30.671875 313.82812 29.421875Q314.39062 28.15625 315.53125 27.53125Q316.67188 26.890625 318.01562 26.890625Q319.70312 26.890625 320.76562 27.75Q321.84375 28.609375 322.15625 30.171875L320.4375 30.4375Q320.20312 29.390625 319.57812 28.875Q318.95312 28.34375 318.07812 28.34375Q316.75 28.34375 315.92188 29.296875Q315.09375 30.25 315.09375 32.296875Q315.09375 34.390625 315.89062 35.34375Q316.6875 36.28125 317.98438 36.28125Q319.01562 36.28125 319.70312 35.65625Q320.40625 35.015625 320.59375 33.703125ZM323.8125 37.5L323.8125 23.1875L325.57812 23.1875L325.57812 28.3125Q326.8125 26.890625 328.6875 26.890625Q329.82812 26.890625 330.67188 27.34375Q331.53125 27.796875 331.89062 28.609375Q332.26562 29.40625 332.26562 30.921875L332.26562 37.5L330.51562 37.5L330.51562 30.921875Q330.51562 29.609375 329.9375 29.015625Q329.35938 28.40625 328.32812 28.40625Q327.54688 28.40625 326.84375 28.8125Q326.15625 29.21875 325.85938 29.921875Q325.57812 30.609375 325.57812 31.828125L325.57812 37.5L323.8125 37.5ZM334.8125 37.5L334.8125 27.125L336.39062 27.125L336.39062 28.578125Q336.875 27.828125 337.6875 27.359375Q338.5 26.890625 339.53125 26.890625Q340.6875 26.890625 341.42188 27.375Q342.15625 27.84375 342.46875 28.703125Q343.70312 26.890625 345.67188 26.890625Q347.21875 26.890625 348.04688 27.75Q348.875 28.609375 348.875 30.375L348.875 37.5L347.125 37.5L347.125 30.96875Q347.125 29.90625 346.95312 29.453125Q346.78125 28.984375 346.32812 28.703125Q345.89062 28.421875 345.28125 28.421875Q344.1875 28.421875 343.45312 29.15625Q342.73438 29.875 342.73438 31.46875L342.73438 37.5L340.98438 37.5L340.98438 30.765625Q340.98438 29.59375 340.54688 29.015625Q340.125 28.421875 339.14062 28.421875Q338.40625 28.421875 337.76562 28.8125Q337.14062 29.203125 336.85938 29.953125Q336.57812 30.703125 336.57812 32.125L336.57812 37.5L334.8125 37.5ZM358.59375 36.21875Q357.60938 37.046875 356.70312 37.390625Q355.79688 37.734375 354.76562 37.734375Q353.0625 37.734375 352.14062 36.90625Q351.21875 36.0625 351.21875 34.765625Q351.21875 34.0 351.5625 33.375Q351.92188 32.75 352.48438 32.375Q353.04688 31.984375 353.75 31.78125Q354.26562 31.65625 355.3125 31.515625Q357.4375 31.265625 358.4375 30.921875Q358.45312 30.5625 358.45312 30.453125Q358.45312 29.390625 357.95312 28.9375Q357.28125 28.34375 355.95312 28.34375Q354.70312 28.34375 354.10938 28.78125Q353.53125 29.21875 353.25 30.328125L351.53125 30.09375Q351.76562 28.984375 352.29688 28.3125Q352.82812 27.625 353.84375 27.265625Q354.85938 26.890625 356.20312 26.890625Q357.53125 26.890625 358.35938 27.203125Q359.1875 27.515625 359.57812 28.0Q359.96875 28.46875 360.125 29.1875Q360.21875 29.640625 360.21875 30.8125L360.21875 33.15625Q360.21875 35.609375 360.32812 36.265625Q360.4375 36.90625 360.78125 37.5L358.9375 37.5Q358.67188 36.953125 358.59375 36.21875ZM358.4375 32.296875Q357.48438 32.6875 355.5625 32.953125Q354.48438 33.109375 354.03125 33.3125Q353.59375 33.5 353.34375 33.875Q353.09375 34.25 353.09375 34.71875Q353.09375 35.421875 353.625 35.890625Q354.15625 36.359375 355.1875 36.359375Q356.20312 36.359375 356.98438 35.921875Q357.78125 35.46875 358.15625 34.703125Q358.4375 34.09375 358.4375 32.9375L358.4375 32.296875ZM362.79688 37.5L362.79688 27.125L364.375 27.125L364.375 28.703125Q364.98438 27.59375 365.5 27.25Q366.01562 26.890625 366.625 26.890625Q367.51562 26.890625 368.4375 27.453125L367.82812 29.09375Q367.1875 28.703125 366.54688 28.703125Q365.96875 28.703125 365.5 29.0625Q365.04688 29.40625 364.84375 30.015625Q364.5625 30.953125 364.5625 32.0625L364.5625 37.5L362.79688 37.5ZM369.82812 37.5L369.82812 23.1875L371.59375 23.1875L371.59375 31.34375L375.75 27.125L378.01562 27.125L374.0625 30.96875L378.42188 37.5L376.25 37.5L372.82812 32.203125L371.59375 33.390625L371.59375 37.5L369.82812 37.5ZM379.10938 34.40625L380.85938 34.125Q381.0 35.171875 381.67188 35.734375Q382.34375 36.28125 383.54688 36.28125Q384.75 36.28125 385.32812 35.796875Q385.92188 35.296875 385.92188 34.640625Q385.92188 34.046875 385.40625 33.703125Q385.04688 33.46875 383.60938 33.109375Q381.67188 32.609375 380.92188 32.265625Q380.1875 31.90625 379.79688 31.28125Q379.40625 30.640625 379.40625 29.875Q379.40625 29.1875 379.71875 28.59375Q380.04688 28.0 380.59375 27.609375Q381.0 27.3125 381.70312 27.109375Q382.42188 26.890625 383.23438 26.890625Q384.45312 26.890625 385.375 27.25Q386.29688 27.59375 386.73438 28.203125Q387.17188 28.796875 387.34375 29.796875L385.625 30.03125Q385.5 29.234375 384.9375 28.796875Q384.375 28.34375 383.35938 28.34375Q382.14062 28.34375 381.625 28.75Q381.10938 29.140625 381.10938 29.671875Q381.10938 30.015625 381.32812 30.296875Q381.53125 30.578125 382.0 30.765625Q382.26562 30.859375 383.54688 31.203125Q385.42188 31.703125 386.15625 32.03125Q386.89062 32.34375 387.3125 32.953125Q387.73438 33.546875 387.73438 34.453125Q387.73438 35.328125 387.21875 36.109375Q386.70312 36.890625 385.73438 37.3125Q384.76562 37.734375 383.54688 37.734375Q381.53125 37.734375 380.46875 36.890625Q379.40625 36.046875 379.10938 34.40625ZM399.17188 41.703125Q397.71875 39.875 396.71875 37.421875Q395.71875 34.953125 395.71875 32.3125Q395.71875 29.984375 396.46875 27.859375Q397.34375 25.390625 399.17188 22.9375L400.4375 22.9375Q399.25 24.96875 398.875 25.84375Q398.28125 27.1875 397.9375 28.65625Q397.51562 30.484375 397.51562 32.328125Q397.51562 37.015625 400.4375 41.703125L399.17188 41.703125ZM402.8125 37.5L402.8125 23.1875L404.57812 23.1875L404.57812 28.3125Q405.8125 26.890625 407.6875 26.890625Q408.82812 26.890625 409.67188 27.34375Q410.53125 27.796875 410.89062 28.609375Q411.26562 29.40625 411.26562 30.921875L411.26562 37.5L409.51562 37.5L409.51562 30.921875Q409.51562 29.609375 408.9375 29.015625Q408.35938 28.40625 407.32812 28.40625Q406.54688 28.40625 405.84375 28.8125Q405.15625 29.21875 404.85938 29.921875Q404.57812 30.609375 404.57812 31.828125L404.57812 37.5L402.8125 37.5ZM413.82812 25.203125L413.82812 23.1875L415.59375 23.1875L415.59375 25.203125L413.82812 25.203125ZM413.82812 37.5L413.82812 27.125L415.59375 27.125L415.59375 37.5L413.82812 37.5ZM417.5 38.359375L419.20312 38.609375Q419.3125 39.40625 419.79688 39.765625Q420.45312 40.25 421.59375 40.25Q422.8125 40.25 423.46875 39.765625Q424.14062 39.28125 424.375 38.40625Q424.51562 37.859375 424.5 36.140625Q423.34375 37.5 421.625 37.5Q419.48438 37.5 418.3125 35.953125Q417.14062 34.40625 417.14062 32.25Q417.14062 30.765625 417.67188 29.515625Q418.21875 28.265625 419.23438 27.578125Q420.26562 26.890625 421.64062 26.890625Q423.46875 26.890625 424.67188 28.375L424.67188 27.125L426.28125 27.125L426.28125 36.09375Q426.28125 38.515625 425.78125 39.515625Q425.29688 40.53125 424.21875 41.109375Q423.15625 41.703125 421.59375 41.703125Q419.75 41.703125 418.59375 40.875Q417.45312 40.046875 417.5 38.359375ZM418.95312 32.125Q418.95312 34.171875 419.76562 35.109375Q420.57812 36.046875 421.79688 36.046875Q423.0 36.046875 423.8125 35.109375Q424.64062 34.171875 424.64062 32.1875Q424.64062 30.28125 423.79688 29.3125Q422.95312 28.34375 421.76562 28.34375Q420.59375 28.34375 419.76562 29.296875Q418.95312 30.25 418.95312 32.125ZM428.8125 37.5L428.8125 23.1875L430.57812 23.1875L430.57812 28.3125Q431.8125 26.890625 433.6875 26.890625Q434.82812 26.890625 435.67188 27.34375Q436.53125 27.796875 436.89062 28.609375Q437.26562 29.40625 437.26562 30.921875L437.26562 37.5L435.51562 37.5L435.51562 30.921875Q435.51562 29.609375 434.9375 29.015625Q434.35938 28.40625 433.32812 28.40625Q432.54688 28.40625 431.84375 28.8125Q431.15625 29.21875 430.85938 29.921875Q430.57812 30.609375 430.57812 31.828125L430.57812 37.5L428.8125 37.5ZM446.92188 34.15625L448.73438 34.390625Q448.3125 35.96875 447.14062 36.859375Q445.98438 37.734375 444.17188 37.734375Q441.90625 37.734375 440.5625 36.34375Q439.23438 34.9375 439.23438 32.40625Q439.23438 29.78125 440.57812 28.34375Q441.92188 26.890625 444.07812 26.890625Q446.15625 26.890625 447.46875 28.3125Q448.79688 29.71875 448.79688 32.296875Q448.79688 32.453125 448.78125 32.765625L441.04688 32.765625Q441.14062 34.46875 442.01562 35.375Q442.89062 36.28125 444.1875 36.28125Q445.15625 36.28125 445.82812 35.78125Q446.51562 35.265625 446.92188 34.15625ZM441.14062 31.3125L446.9375 31.3125Q446.82812 30.015625 446.28125 29.359375Q445.4375 28.34375 444.09375 28.34375Q442.89062 28.34375 442.0625 29.15625Q441.23438 29.953125 441.14062 31.3125ZM450.79688 37.5L450.79688 27.125L452.375 27.125L452.375 28.703125Q452.98438 27.59375 453.5 27.25Q454.01562 26.890625 454.625 26.890625Q455.51562 26.890625 456.4375 27.453125L455.82812 29.09375Q455.1875 28.703125 454.54688 28.703125Q453.96875 28.703125 453.5 29.0625Q453.04688 29.40625 452.84375 30.015625Q452.5625 30.953125 452.5625 32.0625L452.5625 37.5L450.79688 37.5ZM463.82812 25.203125L463.82812 23.1875L465.59375 23.1875L465.59375 25.203125L463.82812 25.203125ZM463.82812 37.5L463.82812 27.125L465.59375 27.125L465.59375 37.5L463.82812 37.5ZM467.10938 34.40625L468.85938 34.125Q469.0 35.171875 469.67188 35.734375Q470.34375 36.28125 471.54688 36.28125Q472.75 36.28125 473.32812 35.796875Q473.92188 35.296875 473.92188 34.640625Q473.92188 34.046875 473.40625 33.703125Q473.04688 33.46875 471.60938 33.109375Q469.67188 32.609375 468.92188 32.265625Q468.1875 31.90625 467.79688 31.28125Q467.40625 30.640625 467.40625 29.875Q467.40625 29.1875 467.71875 28.59375Q468.04688 28.0 468.59375 27.609375Q469.0 27.3125 469.70312 27.109375Q470.42188 26.890625 471.23438 26.890625Q472.45312 26.890625 473.375 27.25Q474.29688 27.59375 474.73438 28.203125Q475.17188 28.796875 475.34375 29.796875L473.625 30.03125Q473.5 29.234375 472.9375 28.796875Q472.375 28.34375 471.35938 28.34375Q470.14062 28.34375 469.625 28.75Q469.10938 29.140625 469.10938 29.671875Q469.10938 30.015625 469.32812 30.296875Q469.53125 30.578125 470.0 30.765625Q470.26562 30.859375 471.54688 31.203125Q473.42188 31.703125 474.15625 32.03125Q474.89062 32.34375 475.3125 32.953125Q475.73438 33.546875 475.73438 34.453125Q475.73438 35.328125 475.21875 36.109375Q474.70312 36.890625 473.73438 37.3125Q472.76562 37.734375 471.54688 37.734375Q469.53125 37.734375 468.46875 36.890625Q467.40625 36.046875 467.10938 34.40625ZM485.4375 37.5L483.8125 37.5L483.8125 23.1875L485.5625 23.1875L485.5625 28.296875Q486.6875 26.890625 488.40625 26.890625Q489.35938 26.890625 490.21875 27.28125Q491.07812 27.671875 491.625 28.375Q492.17188 29.0625 492.48438 30.046875Q492.79688 31.03125 492.79688 32.15625Q492.79688 34.828125 491.48438 36.28125Q490.17188 37.734375 488.32812 37.734375Q486.48438 37.734375 485.4375 36.203125L485.4375 37.5ZM485.42188 32.234375Q485.42188 34.09375 485.92188 34.9375Q486.76562 36.28125 488.17188 36.28125Q489.32812 36.28125 490.15625 35.28125Q491.0 34.28125 491.0 32.296875Q491.0 30.265625 490.1875 29.3125Q489.39062 28.34375 488.25 28.34375Q487.09375 28.34375 486.25 29.34375Q485.42188 30.34375 485.42188 32.234375ZM501.92188 34.15625L503.73438 34.390625Q503.3125 35.96875 502.14062 36.859375Q500.98438 37.734375 499.17188 37.734375Q496.90625 37.734375 495.5625 36.34375Q494.23438 34.9375 494.23438 32.40625Q494.23438 29.78125 495.57812 28.34375Q496.92188 26.890625 499.07812 26.890625Q501.15625 26.890625 502.46875 28.3125Q503.79688 29.71875 503.79688 32.296875Q503.79688 32.453125 503.78125 32.765625L496.04688 32.765625Q496.14062 34.46875 497.01562 35.375Q497.89062 36.28125 499.1875 36.28125Q500.15625 36.28125 500.82812 35.78125Q501.51562 35.265625 501.92188 34.15625ZM496.14062 31.3125L501.9375 31.3125Q501.82812 30.015625 501.28125 29.359375Q500.4375 28.34375 499.09375 28.34375Q497.89062 28.34375 497.0625 29.15625Q496.23438 29.953125 496.14062 31.3125ZM509.65625 35.921875L509.90625 37.484375Q509.17188 37.640625 508.57812 37.640625Q507.625 37.640625 507.09375 37.34375Q506.57812 37.03125 506.35938 36.546875Q506.14062 36.046875 506.14062 34.46875L506.14062 28.5L504.85938 28.5L504.85938 27.125L506.14062 27.125L506.14062 24.5625L507.89062 23.5L507.89062 27.125L509.65625 27.125L509.65625 28.5L507.89062 28.5L507.89062 34.5625Q507.89062 35.3125 507.98438 35.53125Q508.07812 35.734375 508.28125 35.875Q508.5 36.0 508.89062 36.0Q509.17188 36.0 509.65625 35.921875ZM515.65625 35.921875L515.90625 37.484375Q515.1719 37.640625 514.5781 37.640625Q513.625 37.640625 513.09375 37.34375Q512.5781 37.03125 512.3594 36.546875Q512.1406 36.046875 512.1406 34.46875L512.1406 28.5L510.85938 28.5L510.85938 27.125L512.1406 27.125L512.1406 24.5625L513.8906 23.5L513.8906 27.125L515.65625 27.125L515.65625 28.5L513.8906 28.5L513.8906 34.5625Q513.8906 35.3125 513.9844 35.53125Q514.0781 35.734375 514.28125 35.875Q514.5 36.0 514.8906 36.0Q515.1719 36.0 515.65625 35.921875ZM524.9219 34.15625L526.7344 34.390625Q526.3125 35.96875 525.1406 36.859375Q523.9844 37.734375 522.1719 37.734375Q519.90625 37.734375 518.5625 36.34375Q517.2344 34.9375 517.2344 32.40625Q517.2344 29.78125 518.5781 28.34375Q519.9219 26.890625 522.0781 26.890625Q524.15625 26.890625 525.46875 28.3125Q526.7969 29.71875 526.7969 32.296875Q526.7969 32.453125 526.78125 32.765625L519.0469 32.765625Q519.1406 34.46875 520.0156 35.375Q520.8906 36.28125 522.1875 36.28125Q523.15625 36.28125 523.8281 35.78125Q524.5156 35.265625 524.9219 34.15625ZM519.1406 31.3125L524.9375 31.3125Q524.8281 30.015625 524.28125 29.359375Q523.4375 28.34375 522.09375 28.34375Q520.8906 28.34375 520.0625 29.15625Q519.2344 29.953125 519.1406 31.3125ZM528.7969 37.5L528.7969 27.125L530.375 27.125L530.375 28.703125Q530.9844 27.59375 531.5 27.25Q532.0156 26.890625 532.625 26.890625Q533.5156 26.890625 534.4375 27.453125L533.8281 29.09375Q533.1875 28.703125 532.5469 28.703125Q531.96875 28.703125 531.5 29.0625Q531.0469 29.40625 530.84375 30.015625Q530.5625 30.953125 530.5625 32.0625L530.5625 37.5L528.7969 37.5ZM536.96875 41.703125L535.71875 41.703125Q538.625 37.015625 538.625 32.328125Q538.625 30.484375 538.21875 28.6875Q537.875 27.21875 537.28125 25.875Q536.90625 24.984375 535.71875 22.9375L536.96875 22.9375Q538.8125 25.390625 539.6875 27.859375Q540.4375 29.984375 540.4375 32.3125Q540.4375 34.953125 539.4219 37.421875Q538.4219 39.875 536.96875 41.703125Z" fill-rule="nonzero"/></svg> \ No newline at end of file
diff --git a/LICENSE-APACHE b/LICENSE-APACHE
new file mode 100644
index 0000000..1b5ec8b
--- /dev/null
+++ b/LICENSE-APACHE
@@ -0,0 +1,176 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
diff --git a/LICENSE-MIT b/LICENSE-MIT
new file mode 100644
index 0000000..31aa793
--- /dev/null
+++ b/LICENSE-MIT
@@ -0,0 +1,23 @@
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
index 84a4d14..773da99 100644
--- a/README.md
+++ b/README.md
@@ -1,56 +1,75 @@
-# Microsoft Research Detours Package
+# ZLUDA
-Detours is a software package for monitoring and instrumenting API calls on Windows. Detours
-has been used by many ISVs and is also used by product teams at Microsoft. Detours is now available under
-a standard open source license ([MIT](https://github.com/microsoft/Detours/blob/master/LICENSE.md)). This simplifies licensing for programmers using Detours
-and allows the community to support Detours using open source tools and processes.
+ZLUDA is a drop-in replacement for CUDA on Intel GPU. ZLUDA allows to run unmodified CUDA applications using Intel GPUs with near-native performance (more below). It works with current integrated Intel UHD GPUs and will work with future Intel Xe GPUs
-Detours is compatible with the Windows NT family of
-operating systems: Windows NT, Windows XP, Windows Server 2003, Windows 7,
-Windows 8, and Windows 10. It cannot be used by Windows Store apps
-because Detours requires APIs not available to those applications.
-This repo contains the source code for version 4.0.1 of Detours.
+## Performance
-For technical documentation on Detours, see the [Detours Wiki](https://github.com/microsoft/Detours/wiki).
-For directions on how to build and run samples, see the
-samples [README.txt](https://github.com/Microsoft/Detours/blob/master/samples/README.TXT) file.
+ZLUDA performance has been measured with GeekBench 5.2.3 on Intel UHD 630.\
+One measurement has been done using OpenCL and another measurement has been done using CUDA with Intel GPU masquerading as a (relatively slow) NVIDIA GPU with the help of ZLUDA. Both measurements use the same GPU.
-## Contributing
+Performance below is normalized to OpenCL performance. 110% means that ZLUDA-implemented CUDA is 10% faster on Intel UHD 630.
-The [`Detours`](https://github.com/microsoft/detours) repository is where development is done.
-Here are some ways you can participate in the project:
+![Performance graph](GeekBench_5_2_3.svg)
-* [Answer questions](https://github.com/microsoft/detours/issues) about using Detours.
-* [Improve the Wiki](https://github.com/microsoft/detours/wiki).
-* [Submit bugs](https://github.com/microsoft/detours/issues) and help us verify fixes and changes as they are checked in.
-* Review [source code changes](https://github.com/microsoft/detours/pulls).
+[ZLUDA detailed log on Geekbench.com](https://browser.geekbench.com/v5/compute/1918048)
-Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that
-you have the right to, and actually do, grant us the rights to use your contribution.
-For details, visit https://cla.opensource.microsoft.com.
+[OpenCL detailed log on Geekbench.com](https://browser.geekbench.com/v5/compute/1918080)
-When you submit a pull request, a CLA bot will automatically determine whether you need to provide
-a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
-provided by the bot. You will only need to do this once across all repos using our CLA.
+Overall in this suite of benchmarks faster by approximately 4% on ZLUDA.
-This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [[email protected]](mailto:[email protected]) with any additional questions or comments.
+### Explanation of the results
+ * Why is ZLUDA faster in Stereo Matching, Gaussian Blur and Depth of Field?\
+ This has not been precisely pinpointed to one thing or another but it's likely a combination of things:
+ * ZLUDA uses Level 0, which in general is a more level, higher performance API
+ * Tying to the previous point, currently ZLUDA does not support asynchronous execution. This gives us an unfair advantage in a benchmark like GeekBench. GeekBench exclusively uses CUDA synchronous APIs
+ * There is a set of GPU instructions which are available on both NVIDIA hardware and Intel hardware, but are not exposed through OpenCL. We are comparing NVIDIA GPU optimized code with the more general OpenCL code. It's a lucky coincidence (and a credit to the underlying Intel Graphics Compiler) that this code also works well on an Intel GPU
+ * Why is OpenCL faster in Canny and Horizon Detection?\
+ Authors of CUDA benchmarks used CUDA functions `atomicInc` and `atomicDec` which have direct hardware support on NVIDIA cards, but no hardware support on Intel cards. They have to be emulated in software, which limits performance
+ * Why are some benchmarks failing?\
+ ZLUDA itself supports all the operations used in the failing benchmarks. From the limited debugging that has been done so far, the problem is most likely somewhere else. Intel GPU compiler stack is very capable when it comes to compiling OpenCL, C for Metal and DPC++. It's not yet very good at compiling ZLUDA. ZLUDA emits code patterns never seen before by the Intel GPU compiler stack and hits some rarely used (or not used before) code paths in the compiler.\
+ Current status of failing GeekBench tests is tracked [here](https://github.com/vosen/ZLUDA/pull/12)
+
-## Issues, questions, and feedback
+## Details
-* Open an issue on [GitHub Issues](https://github.com/Microsoft/detours/issues).
+ * Is ZLUDA a drop-in replacement for CUDA?\
+ Yes, but certain applications use CUDA in ways which make it incompatible with ZLUDA.
+ * What is the status of the project\
+ This project is a Proof of Concept. About the only thing that works currently is Geekbench (and not even completely). It's amazingly buggy and incomplete. You should not rely on it for anything serious
+ * Is it an Intel project? Is it an NVIDIA project?\
+ No, it's a private project
+ * What is the performance?\
+ Performance can be clode to the performance of similarly written OpenCL code (see GeekBench results in the previous section). NVIDIA GPUs and Intel GPUs have different architecture and feature set. Consequently, certain NVIDIA features have to be emulated in ZLUDA with performance penalty. Additionally, performance of ZLUDA will be always lower than the performance of code specifically optimized for Intel GPUs
+ * How it's different from AMD HIP or Intel DPC++ Compatibility toolkit?\
+ Both are porting toolkits which require programmer's effort to port applications to the API in question. With ZLUDA existing applications "just work" on an Intel GPU (if you are lucky and ZLUDA supports the particular subset of CUDA)
+ * Which Intel GPU are supported?\
+ Intel Gen9 and newer (Skylake and newer) which are supported by Intel Level 0
+ * Does ZLUDA support AMD GPUs?\
+ Certainly not currently, but it might be technically possible
-## Mailing list for announcements
-The detours-announce mailing list is a low-traffic email list for important announcements
-about the project, such as the availability of new versions of Detours. To join it, send
-an email to [email protected] with a
-message body containing only the text SUBSCRIBE DETOURS-ANNOUNCE.
-To leave it, send an email to [email protected] with a
-message body containing only the text UNSUBSCRIBE DETOURS-ANNOUNCE.
+## Usage
+**Warning**: this is a very incomplete Proof of Concept. It's probably not going to work with your application. ZLUDA currently works only with applications which use CUDA Driver API. Linux builds also work with applications which use statically-linked CUDA Runtime API
+### Windows
+You should have the most recent GPU drivers installed.\
+Copy `nvcuda.dll` to the application directory (the directory where .exe file is) and launch it normally
-## License
+### Linux
+A very recent version of [compute-runtime](https://github.com/intel/compute-runtime) is required. At the time of the writing 20.45.18403 is the recommended version.
+Unpack the archive somewhere and run your application like this:
+```
+LD_LIBRARY_PATH=<PATH_TO_THE_DIRECTORY_WITH_ZLUDA_PROVIDED_LIBCUDA> <YOUR_APPLICATION>
+```
+
+## Building
+You should have a relatively recent version of Rust installed, then you just do:
-Copyright (c) Microsoft Corporation. All rights reserved.
+```
+cargo build
+```
+in the main directory of the project
+
+## License
-Licensed under the [MIT](LICENSE.md) License.
+This software is dual-licensed under either the Apache 2.0 license or the MIT license. See [LICENSE-APACHE](LICENSE-APACHE) or [LICENSE-MIT](LICENSE-MIT) for details
diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/ext/detours/.github/ISSUE_TEMPLATE/bug-report.md
index 7967bfa..7967bfa 100644
--- a/.github/ISSUE_TEMPLATE/bug-report.md
+++ b/ext/detours/.github/ISSUE_TEMPLATE/bug-report.md
diff --git a/.github/ISSUE_TEMPLATE/question.md b/ext/detours/.github/ISSUE_TEMPLATE/question.md
index cd9dec3..cd9dec3 100644
--- a/.github/ISSUE_TEMPLATE/question.md
+++ b/ext/detours/.github/ISSUE_TEMPLATE/question.md
diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/ext/detours/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
index 648b62c..648b62c 100644
--- a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
+++ b/ext/detours/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md
diff --git a/.github/codeql/codeql-config.yml b/ext/detours/.github/codeql/codeql-config.yml
index cf9e0c1..cf9e0c1 100644
--- a/.github/codeql/codeql-config.yml
+++ b/ext/detours/.github/codeql/codeql-config.yml
diff --git a/.github/workflows/main.yml b/ext/detours/.github/workflows/main.yml
index c7fedcd..c7fedcd 100644
--- a/.github/workflows/main.yml
+++ b/ext/detours/.github/workflows/main.yml
diff --git a/ext/detours/.gitignore b/ext/detours/.gitignore
new file mode 100644
index 0000000..b5a68d4
--- /dev/null
+++ b/ext/detours/.gitignore
@@ -0,0 +1,41 @@
+# C extensions
+*.so
+
+# Unit test / coverage reports
+.coverage
+.tox
+nosetests.xml
+
+# Translations
+*.mo
+
+# Mr Developer
+.mr.developer.cfg
+.project
+.pydevproject
+
+# vim
+*~
+*.swp
+
+# Visual Studio build
+*.ipch
+.vs/
+output/
+include/
+*.exp
+*.pdb
+*.lib
+*.dll
+*.exe
+obj.*
+*.ipdb
+*.iobj
+*.tlog
+*.log
+*.obj
+*.user
+*.recipe
+/bin.*
+*.vcxproj.FileListAbsolute.txt
+*.vcxprojAssemblyReference.cache
diff --git a/CREDITS.TXT b/ext/detours/CREDITS.TXT
index 275b5f0..275b5f0 100644
--- a/CREDITS.TXT
+++ b/ext/detours/CREDITS.TXT
diff --git a/LICENSE.md b/ext/detours/LICENSE.md
index e6a4c56..e6a4c56 100644
--- a/LICENSE.md
+++ b/ext/detours/LICENSE.md
diff --git a/Makefile b/ext/detours/Makefile
index 78ef9d0..78ef9d0 100644
--- a/Makefile
+++ b/ext/detours/Makefile
diff --git a/ext/detours/README.md b/ext/detours/README.md
new file mode 100644
index 0000000..84a4d14
--- /dev/null
+++ b/ext/detours/README.md
@@ -0,0 +1,56 @@
+# Microsoft Research Detours Package
+
+Detours is a software package for monitoring and instrumenting API calls on Windows. Detours
+has been used by many ISVs and is also used by product teams at Microsoft. Detours is now available under
+a standard open source license ([MIT](https://github.com/microsoft/Detours/blob/master/LICENSE.md)). This simplifies licensing for programmers using Detours
+and allows the community to support Detours using open source tools and processes.
+
+Detours is compatible with the Windows NT family of
+operating systems: Windows NT, Windows XP, Windows Server 2003, Windows 7,
+Windows 8, and Windows 10. It cannot be used by Windows Store apps
+because Detours requires APIs not available to those applications.
+This repo contains the source code for version 4.0.1 of Detours.
+
+For technical documentation on Detours, see the [Detours Wiki](https://github.com/microsoft/Detours/wiki).
+For directions on how to build and run samples, see the
+samples [README.txt](https://github.com/Microsoft/Detours/blob/master/samples/README.TXT) file.
+
+## Contributing
+
+The [`Detours`](https://github.com/microsoft/detours) repository is where development is done.
+Here are some ways you can participate in the project:
+
+* [Answer questions](https://github.com/microsoft/detours/issues) about using Detours.
+* [Improve the Wiki](https://github.com/microsoft/detours/wiki).
+* [Submit bugs](https://github.com/microsoft/detours/issues) and help us verify fixes and changes as they are checked in.
+* Review [source code changes](https://github.com/microsoft/detours/pulls).
+
+Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that
+you have the right to, and actually do, grant us the rights to use your contribution.
+For details, visit https://cla.opensource.microsoft.com.
+
+When you submit a pull request, a CLA bot will automatically determine whether you need to provide
+a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
+provided by the bot. You will only need to do this once across all repos using our CLA.
+
+This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [[email protected]](mailto:[email protected]) with any additional questions or comments.
+
+## Issues, questions, and feedback
+
+* Open an issue on [GitHub Issues](https://github.com/Microsoft/detours/issues).
+
+## Mailing list for announcements
+
+The detours-announce mailing list is a low-traffic email list for important announcements
+about the project, such as the availability of new versions of Detours. To join it, send
+an email to [email protected] with a
+message body containing only the text SUBSCRIBE DETOURS-ANNOUNCE.
+To leave it, send an email to [email protected] with a
+message body containing only the text UNSUBSCRIBE DETOURS-ANNOUNCE.
+
+
+## License
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Licensed under the [MIT](LICENSE.md) License.
diff --git a/samples/Makefile b/ext/detours/samples/Makefile
index 7952095..7952095 100644
--- a/samples/Makefile
+++ b/ext/detours/samples/Makefile
diff --git a/samples/README.TXT b/ext/detours/samples/README.TXT
index 11b8817..11b8817 100644
--- a/samples/README.TXT
+++ b/ext/detours/samples/README.TXT
diff --git a/samples/comeasy/Makefile b/ext/detours/samples/comeasy/Makefile
index 0c3a057..0c3a057 100644
--- a/samples/comeasy/Makefile
+++ b/ext/detours/samples/comeasy/Makefile
diff --git a/samples/comeasy/comeasy.cpp b/ext/detours/samples/comeasy/comeasy.cpp
index e5c66e8..e5c66e8 100644
--- a/samples/comeasy/comeasy.cpp
+++ b/ext/detours/samples/comeasy/comeasy.cpp
diff --git a/samples/comeasy/wrotei.cpp b/ext/detours/samples/comeasy/wrotei.cpp
index 7bd925d..7bd925d 100644
--- a/samples/comeasy/wrotei.cpp
+++ b/ext/detours/samples/comeasy/wrotei.cpp
diff --git a/samples/comeasy/wrotei.rc b/ext/detours/samples/comeasy/wrotei.rc
index 6a51c98..6a51c98 100644
--- a/samples/comeasy/wrotei.rc
+++ b/ext/detours/samples/comeasy/wrotei.rc
diff --git a/samples/commem/Makefile b/ext/detours/samples/commem/Makefile
index 70cdd59..70cdd59 100644
--- a/samples/commem/Makefile
+++ b/ext/detours/samples/commem/Makefile
diff --git a/samples/commem/commem.cpp b/ext/detours/samples/commem/commem.cpp
index 6779843..6779843 100644
--- a/samples/commem/commem.cpp
+++ b/ext/detours/samples/commem/commem.cpp
diff --git a/samples/common.mak b/ext/detours/samples/common.mak
index aa63a15..aa63a15 100644
--- a/samples/common.mak
+++ b/ext/detours/samples/common.mak
diff --git a/samples/cping/Makefile b/ext/detours/samples/cping/Makefile
index cc99a09..cc99a09 100644
--- a/samples/cping/Makefile
+++ b/ext/detours/samples/cping/Makefile
diff --git a/samples/cping/ReadMe.Txt b/ext/detours/samples/cping/ReadMe.Txt
index fea1095..fea1095 100644
--- a/samples/cping/ReadMe.Txt
+++ b/ext/detours/samples/cping/ReadMe.Txt
diff --git a/samples/cping/cping.cpp b/ext/detours/samples/cping/cping.cpp
index 4312341..4312341 100644
--- a/samples/cping/cping.cpp
+++ b/ext/detours/samples/cping/cping.cpp
diff --git a/samples/cping/cping.dat b/ext/detours/samples/cping/cping.dat
index e69de29..e69de29 100644
--- a/samples/cping/cping.dat
+++ b/ext/detours/samples/cping/cping.dat
diff --git a/samples/cping/iping.idl b/ext/detours/samples/cping/iping.idl
index 6713e50..6713e50 100644
--- a/samples/cping/iping.idl
+++ b/ext/detours/samples/cping/iping.idl
diff --git a/samples/disas/Makefile b/ext/detours/samples/disas/Makefile
index ecf0f66..ecf0f66 100644
--- a/samples/disas/Makefile
+++ b/ext/detours/samples/disas/Makefile
diff --git a/samples/disas/arm.asm b/ext/detours/samples/disas/arm.asm
index 10073b7..10073b7 100644
--- a/samples/disas/arm.asm
+++ b/ext/detours/samples/disas/arm.asm
diff --git a/samples/disas/disas.cpp b/ext/detours/samples/disas/disas.cpp
index db8ef6a..db8ef6a 100644
--- a/samples/disas/disas.cpp
+++ b/ext/detours/samples/disas/disas.cpp
diff --git a/samples/disas/ia64.asm b/ext/detours/samples/disas/ia64.asm
index 189eb28..189eb28 100644
--- a/samples/disas/ia64.asm
+++ b/ext/detours/samples/disas/ia64.asm
diff --git a/samples/disas/unk.cpp b/ext/detours/samples/disas/unk.cpp
index ff9bfe6..ff9bfe6 100644
--- a/samples/disas/unk.cpp
+++ b/ext/detours/samples/disas/unk.cpp
diff --git a/samples/disas/x64.asm b/ext/detours/samples/disas/x64.asm
index a60d4dc..a60d4dc 100644
--- a/samples/disas/x64.asm
+++ b/ext/detours/samples/disas/x64.asm
diff --git a/samples/disas/x86.cpp b/ext/detours/samples/disas/x86.cpp
index ac39de7..ac39de7 100644
--- a/samples/disas/x86.cpp
+++ b/ext/detours/samples/disas/x86.cpp
diff --git a/samples/dtest/Makefile b/ext/detours/samples/dtest/Makefile
index 1179c19..1179c19 100644
--- a/samples/dtest/Makefile
+++ b/ext/detours/samples/dtest/Makefile
diff --git a/samples/dtest/NORMAL_IA64.TXT b/ext/detours/samples/dtest/NORMAL_IA64.TXT
index f87afa5..f87afa5 100644
--- a/samples/dtest/NORMAL_IA64.TXT
+++ b/ext/detours/samples/dtest/NORMAL_IA64.TXT
diff --git a/samples/dtest/NORMAL_X64.TXT b/ext/detours/samples/dtest/NORMAL_X64.TXT
index 9758c03..9758c03 100644
--- a/samples/dtest/NORMAL_X64.TXT
+++ b/ext/detours/samples/dtest/NORMAL_X64.TXT
diff --git a/samples/dtest/NORMAL_X86.TXT b/ext/detours/samples/dtest/NORMAL_X86.TXT
index 90ab0c8..90ab0c8 100644
--- a/samples/dtest/NORMAL_X86.TXT
+++ b/ext/detours/samples/dtest/NORMAL_X86.TXT
diff --git a/samples/dtest/dtarge.cpp b/ext/detours/samples/dtest/dtarge.cpp
index 2cd4534..2cd4534 100644
--- a/samples/dtest/dtarge.cpp
+++ b/ext/detours/samples/dtest/dtarge.cpp
diff --git a/samples/dtest/dtarge.h b/ext/detours/samples/dtest/dtarge.h
index 7aa5cd6..7aa5cd6 100644
--- a/samples/dtest/dtarge.h
+++ b/ext/detours/samples/dtest/dtarge.h
diff --git a/samples/dtest/dtarge.rc b/ext/detours/samples/dtest/dtarge.rc
index 1a66b51..1a66b51 100644
--- a/samples/dtest/dtarge.rc
+++ b/ext/detours/samples/dtest/dtarge.rc
diff --git a/samples/dtest/dtest.cpp b/ext/detours/samples/dtest/dtest.cpp
index f7de56d..f7de56d 100644
--- a/samples/dtest/dtest.cpp
+++ b/ext/detours/samples/dtest/dtest.cpp
diff --git a/samples/dumpe/Makefile b/ext/detours/samples/dumpe/Makefile
index bca7481..bca7481 100644
--- a/samples/dumpe/Makefile
+++ b/ext/detours/samples/dumpe/Makefile
diff --git a/samples/dumpe/dumpe.cpp b/ext/detours/samples/dumpe/dumpe.cpp
index 2eac099..2eac099 100644
--- a/samples/dumpe/dumpe.cpp
+++ b/ext/detours/samples/dumpe/dumpe.cpp
diff --git a/samples/dumpi/Makefile b/ext/detours/samples/dumpi/Makefile
index 641f86a..641f86a 100644
--- a/samples/dumpi/Makefile
+++ b/ext/detours/samples/dumpi/Makefile
diff --git a/samples/dumpi/dumpi.cpp b/ext/detours/samples/dumpi/dumpi.cpp
index be63648..be63648 100644
--- a/samples/dumpi/dumpi.cpp
+++ b/ext/detours/samples/dumpi/dumpi.cpp
diff --git a/samples/dynamic_alloc/Makefile b/ext/detours/samples/dynamic_alloc/Makefile
index 3e22279..3e22279 100644
--- a/samples/dynamic_alloc/Makefile
+++ b/ext/detours/samples/dynamic_alloc/Makefile
diff --git a/samples/dynamic_alloc/main.cpp b/ext/detours/samples/dynamic_alloc/main.cpp
index a61232f..a61232f 100644
--- a/samples/dynamic_alloc/main.cpp
+++ b/ext/detours/samples/dynamic_alloc/main.cpp
diff --git a/samples/dynamic_alloc/x64.asm b/ext/detours/samples/dynamic_alloc/x64.asm
index d11be8a..d11be8a 100644
--- a/samples/dynamic_alloc/x64.asm
+++ b/ext/detours/samples/dynamic_alloc/x64.asm
diff --git a/samples/dynamic_alloc/x86.asm b/ext/detours/samples/dynamic_alloc/x86.asm
index f188e8b..f188e8b 100644
--- a/samples/dynamic_alloc/x86.asm
+++ b/ext/detours/samples/dynamic_alloc/x86.asm
diff --git a/samples/echo/Makefile b/ext/detours/samples/echo/Makefile
index 366d739..366d739 100644
--- a/samples/echo/Makefile
+++ b/ext/detours/samples/echo/Makefile
diff --git a/samples/echo/echofx.cpp b/ext/detours/samples/echo/echofx.cpp
index 73b5a7f..73b5a7f 100644
--- a/samples/echo/echofx.cpp
+++ b/ext/detours/samples/echo/echofx.cpp
diff --git a/samples/echo/echofx.rc b/ext/detours/samples/echo/echofx.rc
index 0afd53c..0afd53c 100644
--- a/samples/echo/echofx.rc
+++ b/ext/detours/samples/echo/echofx.rc
diff --git a/samples/echo/echonul.cpp b/ext/detours/samples/echo/echonul.cpp
index c05777d..c05777d 100644
--- a/samples/echo/echonul.cpp
+++ b/ext/detours/samples/echo/echonul.cpp
diff --git a/samples/echo/main.cpp b/ext/detours/samples/echo/main.cpp
index 0216875..0216875 100644
--- a/samples/echo/main.cpp
+++ b/ext/detours/samples/echo/main.cpp
diff --git a/samples/einst/Makefile b/ext/detours/samples/einst/Makefile
index ea6fea7..ea6fea7 100644
--- a/samples/einst/Makefile
+++ b/ext/detours/samples/einst/Makefile
diff --git a/samples/einst/edll1x.cpp b/ext/detours/samples/einst/edll1x.cpp
index ee0880f..ee0880f 100644
--- a/samples/einst/edll1x.cpp
+++ b/ext/detours/samples/einst/edll1x.cpp
diff --git a/samples/einst/edll2x.cpp b/ext/detours/samples/einst/edll2x.cpp
index 62a5abc..62a5abc 100644
--- a/samples/einst/edll2x.cpp
+++ b/ext/detours/samples/einst/edll2x.cpp
diff --git a/samples/einst/edll3x.cpp b/ext/detours/samples/einst/edll3x.cpp
index 2693d00..2693d00 100644
--- a/samples/einst/edll3x.cpp
+++ b/ext/detours/samples/einst/edll3x.cpp
diff --git a/samples/einst/einst.cpp b/ext/detours/samples/einst/einst.cpp
index e732a1f..e732a1f 100644
--- a/samples/einst/einst.cpp
+++ b/ext/detours/samples/einst/einst.cpp
diff --git a/samples/excep/Makefile b/ext/detours/samples/excep/Makefile
index 42f7d8c..42f7d8c 100644
--- a/samples/excep/Makefile
+++ b/ext/detours/samples/excep/Makefile
diff --git a/samples/excep/excep.cpp b/ext/detours/samples/excep/excep.cpp
index 488a489..488a489 100644
--- a/samples/excep/excep.cpp
+++ b/ext/detours/samples/excep/excep.cpp
diff --git a/samples/excep/firstexc.cpp b/ext/detours/samples/excep/firstexc.cpp
index 4222ba8..4222ba8 100644
--- a/samples/excep/firstexc.cpp
+++ b/ext/detours/samples/excep/firstexc.cpp
diff --git a/samples/excep/firstexc.h b/ext/detours/samples/excep/firstexc.h
index 689c1b4..689c1b4 100644
--- a/samples/excep/firstexc.h
+++ b/ext/detours/samples/excep/firstexc.h
diff --git a/samples/findfunc/Makefile b/ext/detours/samples/findfunc/Makefile
index 2ea19dc..2ea19dc 100644
--- a/samples/findfunc/Makefile
+++ b/ext/detours/samples/findfunc/Makefile
diff --git a/samples/findfunc/extend.cpp b/ext/detours/samples/findfunc/extend.cpp
index 744a3ab..744a3ab 100644
--- a/samples/findfunc/extend.cpp
+++ b/ext/detours/samples/findfunc/extend.cpp
diff --git a/samples/findfunc/extend.rc b/ext/detours/samples/findfunc/extend.rc
index a6e3f52..a6e3f52 100644
--- a/samples/findfunc/extend.rc
+++ b/ext/detours/samples/findfunc/extend.rc
diff --git a/samples/findfunc/findfunc.cpp b/ext/detours/samples/findfunc/findfunc.cpp
index 3c7f15b..3c7f15b 100644
--- a/samples/findfunc/findfunc.cpp
+++ b/ext/detours/samples/findfunc/findfunc.cpp
diff --git a/samples/findfunc/symtest.cpp b/ext/detours/samples/findfunc/symtest.cpp
index 74cd539..74cd539 100644
--- a/samples/findfunc/symtest.cpp
+++ b/ext/detours/samples/findfunc/symtest.cpp
diff --git a/samples/findfunc/target.cpp b/ext/detours/samples/findfunc/target.cpp
index 052e2ab..052e2ab 100644
--- a/samples/findfunc/target.cpp
+++ b/ext/detours/samples/findfunc/target.cpp
diff --git a/samples/findfunc/target.h b/ext/detours/samples/findfunc/target.h
index 076da2e..076da2e 100644
--- a/samples/findfunc/target.h
+++ b/ext/detours/samples/findfunc/target.h
diff --git a/samples/findfunc/target.rc b/ext/detours/samples/findfunc/target.rc
index b75e4ec..b75e4ec 100644
--- a/samples/findfunc/target.rc
+++ b/ext/detours/samples/findfunc/target.rc
diff --git a/samples/impmunge/Makefile b/ext/detours/samples/impmunge/Makefile
index e320b0c..e320b0c 100644
--- a/samples/impmunge/Makefile
+++ b/ext/detours/samples/impmunge/Makefile
diff --git a/samples/impmunge/impmunge.cpp b/ext/detours/samples/impmunge/impmunge.cpp
index 95516dc..95516dc 100644
--- a/samples/impmunge/impmunge.cpp
+++ b/ext/detours/samples/impmunge/impmunge.cpp
diff --git a/samples/member/Makefile b/ext/detours/samples/member/Makefile
index 7ecf505..7ecf505 100644
--- a/samples/member/Makefile
+++ b/ext/detours/samples/member/Makefile
diff --git a/samples/member/member.cpp b/ext/detours/samples/member/member.cpp
index 585ef98..585ef98 100644
--- a/samples/member/member.cpp
+++ b/ext/detours/samples/member/member.cpp
diff --git a/samples/opengl/Makefile b/ext/detours/samples/opengl/Makefile
index 33d522d..33d522d 100644
--- a/samples/opengl/Makefile
+++ b/ext/detours/samples/opengl/Makefile
diff --git a/samples/opengl/ogldet.cpp b/ext/detours/samples/opengl/ogldet.cpp
index b1659d9..b1659d9 100644
--- a/samples/opengl/ogldet.cpp
+++ b/ext/detours/samples/opengl/ogldet.cpp
diff --git a/samples/opengl/ogldet.rc b/ext/detours/samples/opengl/ogldet.rc
index b25480d..b25480d 100644
--- a/samples/opengl/ogldet.rc
+++ b/ext/detours/samples/opengl/ogldet.rc
diff --git a/samples/opengl/testogl.cpp b/ext/detours/samples/opengl/testogl.cpp
index c48b4c1..c48b4c1 100644
--- a/samples/opengl/testogl.cpp
+++ b/ext/detours/samples/opengl/testogl.cpp
diff --git a/samples/region/Makefile b/ext/detours/samples/region/Makefile
index 3d6108f..3d6108f 100644
--- a/samples/region/Makefile
+++ b/ext/detours/samples/region/Makefile
diff --git a/samples/region/region.cpp b/ext/detours/samples/region/region.cpp
index d23f583..d23f583 100644
--- a/samples/region/region.cpp
+++ b/ext/detours/samples/region/region.cpp
diff --git a/samples/setdll/Makefile b/ext/detours/samples/setdll/Makefile
index 36ba377..36ba377 100644
--- a/samples/setdll/Makefile
+++ b/ext/detours/samples/setdll/Makefile
diff --git a/samples/setdll/setdll.cpp b/ext/detours/samples/setdll/setdll.cpp
index fd39b03..fd39b03 100644
--- a/samples/setdll/setdll.cpp
+++ b/ext/detours/samples/setdll/setdll.cpp
diff --git a/samples/simple/Makefile b/ext/detours/samples/simple/Makefile
index 1597519..1597519 100644
--- a/samples/simple/Makefile
+++ b/ext/detours/samples/simple/Makefile
diff --git a/samples/simple/simple.cpp b/ext/detours/samples/simple/simple.cpp
index bc902f1..bc902f1 100644
--- a/samples/simple/simple.cpp
+++ b/ext/detours/samples/simple/simple.cpp
diff --git a/samples/simple/simple.rc b/ext/detours/samples/simple/simple.rc
index f493af4..f493af4 100644
--- a/samples/simple/simple.rc
+++ b/ext/detours/samples/simple/simple.rc
diff --git a/samples/simple/sleep5.cpp b/ext/detours/samples/simple/sleep5.cpp
index bb28226..bb28226 100644
--- a/samples/simple/sleep5.cpp
+++ b/ext/detours/samples/simple/sleep5.cpp
diff --git a/samples/slept/Makefile b/ext/detours/samples/slept/Makefile
index 6711a87..6711a87 100644
--- a/samples/slept/Makefile
+++ b/ext/detours/samples/slept/Makefile
diff --git a/samples/slept/NORMAL_IA64.TXT b/ext/detours/samples/slept/NORMAL_IA64.TXT
index d26c3c3..d26c3c3 100644
--- a/samples/slept/NORMAL_IA64.TXT
+++ b/ext/detours/samples/slept/NORMAL_IA64.TXT
diff --git a/samples/slept/NORMAL_X64.TXT b/ext/detours/samples/slept/NORMAL_X64.TXT
index de33e31..de33e31 100644
--- a/samples/slept/NORMAL_X64.TXT
+++ b/ext/detours/samples/slept/NORMAL_X64.TXT
diff --git a/samples/slept/NORMAL_X86.TXT b/ext/detours/samples/slept/NORMAL_X86.TXT
index 9794e48..9794e48 100644
--- a/samples/slept/NORMAL_X86.TXT
+++ b/ext/detours/samples/slept/NORMAL_X86.TXT
diff --git a/samples/slept/dslept.cpp b/ext/detours/samples/slept/dslept.cpp
index 3929820..3929820 100644
--- a/samples/slept/dslept.cpp
+++ b/ext/detours/samples/slept/dslept.cpp
diff --git a/samples/slept/dslept.rc b/ext/detours/samples/slept/dslept.rc
index c9bc3b7..c9bc3b7 100644
--- a/samples/slept/dslept.rc
+++ b/ext/detours/samples/slept/dslept.rc
diff --git a/samples/slept/sleepbed.cpp b/ext/detours/samples/slept/sleepbed.cpp
index 49b7934..49b7934 100644
--- a/samples/slept/sleepbed.cpp
+++ b/ext/detours/samples/slept/sleepbed.cpp
diff --git a/samples/slept/sleepnew.cpp b/ext/detours/samples/slept/sleepnew.cpp
index a3176f2..a3176f2 100644
--- a/samples/slept/sleepnew.cpp
+++ b/ext/detours/samples/slept/sleepnew.cpp
diff --git a/samples/slept/sleepold.cpp b/ext/detours/samples/slept/sleepold.cpp
index fb3abdd..fb3abdd 100644
--- a/samples/slept/sleepold.cpp
+++ b/ext/detours/samples/slept/sleepold.cpp
diff --git a/samples/slept/slept.cpp b/ext/detours/samples/slept/slept.cpp
index 5903295..5903295 100644
--- a/samples/slept/slept.cpp
+++ b/ext/detours/samples/slept/slept.cpp
diff --git a/samples/slept/slept.h b/ext/detours/samples/slept/slept.h
index 9cc71d8..9cc71d8 100644
--- a/samples/slept/slept.h
+++ b/ext/detours/samples/slept/slept.h
diff --git a/samples/slept/slept.rc b/ext/detours/samples/slept/slept.rc
index 1e5e3a8..1e5e3a8 100644
--- a/samples/slept/slept.rc
+++ b/ext/detours/samples/slept/slept.rc
diff --git a/samples/slept/verify.cpp b/ext/detours/samples/slept/verify.cpp
index d7a38fd..d7a38fd 100644
--- a/samples/slept/verify.cpp
+++ b/ext/detours/samples/slept/verify.cpp
diff --git a/samples/syelog/Makefile b/ext/detours/samples/syelog/Makefile
index 89e7967..89e7967 100644
--- a/samples/syelog/Makefile
+++ b/ext/detours/samples/syelog/Makefile
diff --git a/samples/syelog/sltest.cpp b/ext/detours/samples/syelog/sltest.cpp
index 8377872..8377872 100644
--- a/samples/syelog/sltest.cpp
+++ b/ext/detours/samples/syelog/sltest.cpp
diff --git a/samples/syelog/sltestp.cpp b/ext/detours/samples/syelog/sltestp.cpp
index 50856ac..50856ac 100644
--- a/samples/syelog/sltestp.cpp
+++ b/ext/detours/samples/syelog/sltestp.cpp
diff --git a/samples/syelog/syelog.cpp b/ext/detours/samples/syelog/syelog.cpp
index 72e02e5..72e02e5 100644
--- a/samples/syelog/syelog.cpp
+++ b/ext/detours/samples/syelog/syelog.cpp
diff --git a/samples/syelog/syelog.h b/ext/detours/samples/syelog/syelog.h
index 7cfa9f3..7cfa9f3 100644
--- a/samples/syelog/syelog.h
+++ b/ext/detours/samples/syelog/syelog.h
diff --git a/samples/syelog/syelogd.cpp b/ext/detours/samples/syelog/syelogd.cpp
index c3db446..c3db446 100644
--- a/samples/syelog/syelogd.cpp
+++ b/ext/detours/samples/syelog/syelogd.cpp
diff --git a/samples/talloc/Makefile b/ext/detours/samples/talloc/Makefile
index 9e561c4..9e561c4 100644
--- a/samples/talloc/Makefile
+++ b/ext/detours/samples/talloc/Makefile
diff --git a/samples/talloc/NORMAL_IA64.TXT b/ext/detours/samples/talloc/NORMAL_IA64.TXT
index e04a1c9..e04a1c9 100644
--- a/samples/talloc/NORMAL_IA64.TXT
+++ b/ext/detours/samples/talloc/NORMAL_IA64.TXT
diff --git a/samples/talloc/NORMAL_X64.TXT b/ext/detours/samples/talloc/NORMAL_X64.TXT
index 650d09a..650d09a 100644
--- a/samples/talloc/NORMAL_X64.TXT
+++ b/ext/detours/samples/talloc/NORMAL_X64.TXT
diff --git a/samples/talloc/talloc.cpp b/ext/detours/samples/talloc/talloc.cpp
index 85eb6b3..85eb6b3 100644
--- a/samples/talloc/talloc.cpp
+++ b/ext/detours/samples/talloc/talloc.cpp
diff --git a/samples/talloc/tdll1x.cpp b/ext/detours/samples/talloc/tdll1x.cpp
index 8edbadc..8edbadc 100644
--- a/samples/talloc/tdll1x.cpp
+++ b/ext/detours/samples/talloc/tdll1x.cpp
diff --git a/samples/talloc/tdll2x.cpp b/ext/detours/samples/talloc/tdll2x.cpp
index c7e394f..c7e394f 100644
--- a/samples/talloc/tdll2x.cpp
+++ b/ext/detours/samples/talloc/tdll2x.cpp
diff --git a/samples/talloc/tdll3x.cpp b/ext/detours/samples/talloc/tdll3x.cpp
index d3610e2..d3610e2 100644
--- a/samples/talloc/tdll3x.cpp
+++ b/ext/detours/samples/talloc/tdll3x.cpp
diff --git a/samples/talloc/tdll4x.cpp b/ext/detours/samples/talloc/tdll4x.cpp
index eb3ab1e..eb3ab1e 100644
--- a/samples/talloc/tdll4x.cpp
+++ b/ext/detours/samples/talloc/tdll4x.cpp
diff --git a/samples/talloc/tdll5x.cpp b/ext/detours/samples/talloc/tdll5x.cpp
index 681ce41..681ce41 100644
--- a/samples/talloc/tdll5x.cpp
+++ b/ext/detours/samples/talloc/tdll5x.cpp
diff --git a/samples/talloc/tdll6x.cpp b/ext/detours/samples/talloc/tdll6x.cpp
index da2a306..da2a306 100644
--- a/samples/talloc/tdll6x.cpp
+++ b/ext/detours/samples/talloc/tdll6x.cpp
diff --git a/samples/talloc/tdll7x.cpp b/ext/detours/samples/talloc/tdll7x.cpp
index bcc9927..bcc9927 100644
--- a/samples/talloc/tdll7x.cpp
+++ b/ext/detours/samples/talloc/tdll7x.cpp
diff --git a/samples/talloc/tdll8x.cpp b/ext/detours/samples/talloc/tdll8x.cpp
index 2c899e4..2c899e4 100644
--- a/samples/talloc/tdll8x.cpp
+++ b/ext/detours/samples/talloc/tdll8x.cpp
diff --git a/samples/talloc/tdll9x.cpp b/ext/detours/samples/talloc/tdll9x.cpp
index b8d5c08..b8d5c08 100644
--- a/samples/talloc/tdll9x.cpp
+++ b/ext/detours/samples/talloc/tdll9x.cpp
diff --git a/samples/traceapi/Makefile b/ext/detours/samples/traceapi/Makefile
index 61794b1..61794b1 100644
--- a/samples/traceapi/Makefile
+++ b/ext/detours/samples/traceapi/Makefile
diff --git a/samples/traceapi/_win32.cpp b/ext/detours/samples/traceapi/_win32.cpp
index f28daf3..f28daf3 100644
--- a/samples/traceapi/_win32.cpp
+++ b/ext/detours/samples/traceapi/_win32.cpp
diff --git a/samples/traceapi/testapi.cpp b/ext/detours/samples/traceapi/testapi.cpp
index d85fc02..d85fc02 100644
--- a/samples/traceapi/testapi.cpp
+++ b/ext/detours/samples/traceapi/testapi.cpp
diff --git a/samples/traceapi/trcapi.cpp b/ext/detours/samples/traceapi/trcapi.cpp
index e7b7240..e7b7240 100644
--- a/samples/traceapi/trcapi.cpp
+++ b/ext/detours/samples/traceapi/trcapi.cpp
diff --git a/samples/traceapi/trcapi.rc b/ext/detours/samples/traceapi/trcapi.rc
index dc1975f..dc1975f 100644
--- a/samples/traceapi/trcapi.rc
+++ b/ext/detours/samples/traceapi/trcapi.rc
diff --git a/samples/tracebld/Makefile b/ext/detours/samples/tracebld/Makefile
index 182655d..182655d 100644
--- a/samples/tracebld/Makefile
+++ b/ext/detours/samples/tracebld/Makefile
diff --git a/samples/tracebld/tracebld.cpp b/ext/detours/samples/tracebld/tracebld.cpp
index 7573b4a..7573b4a 100644
--- a/samples/tracebld/tracebld.cpp
+++ b/ext/detours/samples/tracebld/tracebld.cpp
diff --git a/samples/tracebld/tracebld.h b/ext/detours/samples/tracebld/tracebld.h
index 9a878af..9a878af 100644
--- a/samples/tracebld/tracebld.h
+++ b/ext/detours/samples/tracebld/tracebld.h
diff --git a/samples/tracebld/trcbld.cpp b/ext/detours/samples/tracebld/trcbld.cpp
index 5392f90..5392f90 100644
--- a/samples/tracebld/trcbld.cpp
+++ b/ext/detours/samples/tracebld/trcbld.cpp
diff --git a/samples/tracebld/trcbld.rc b/ext/detours/samples/tracebld/trcbld.rc
index 180faec..180faec 100644
--- a/samples/tracebld/trcbld.rc
+++ b/ext/detours/samples/tracebld/trcbld.rc
diff --git a/samples/tracelnk/Makefile b/ext/detours/samples/tracelnk/Makefile
index 067d4fc..067d4fc 100644
--- a/samples/tracelnk/Makefile
+++ b/ext/detours/samples/tracelnk/Makefile
diff --git a/samples/tracelnk/trclnk.cpp b/ext/detours/samples/tracelnk/trclnk.cpp
index 75cbfe2..75cbfe2 100644
--- a/samples/tracelnk/trclnk.cpp
+++ b/ext/detours/samples/tracelnk/trclnk.cpp
diff --git a/samples/tracelnk/trclnk.rc b/ext/detours/samples/tracelnk/trclnk.rc
index 75e08e9..75e08e9 100644
--- a/samples/tracelnk/trclnk.rc
+++ b/ext/detours/samples/tracelnk/trclnk.rc
diff --git a/samples/tracemem/Makefile b/ext/detours/samples/tracemem/Makefile
index fbd6c8d..fbd6c8d 100644
--- a/samples/tracemem/Makefile
+++ b/ext/detours/samples/tracemem/Makefile
diff --git a/samples/tracemem/trcmem.cpp b/ext/detours/samples/tracemem/trcmem.cpp
index 85f72b9..85f72b9 100644
--- a/samples/tracemem/trcmem.cpp
+++ b/ext/detours/samples/tracemem/trcmem.cpp
diff --git a/samples/tracemem/trcmem.rc b/ext/detours/samples/tracemem/trcmem.rc
index 5e911d6..5e911d6 100644
--- a/samples/tracemem/trcmem.rc
+++ b/ext/detours/samples/tracemem/trcmem.rc
diff --git a/samples/tracereg/Makefile b/ext/detours/samples/tracereg/Makefile
index 459747f..459747f 100644
--- a/samples/tracereg/Makefile
+++ b/ext/detours/samples/tracereg/Makefile
diff --git a/samples/tracereg/trcreg.cpp b/ext/detours/samples/tracereg/trcreg.cpp
index 7e1b780..7e1b780 100644
--- a/samples/tracereg/trcreg.cpp
+++ b/ext/detours/samples/tracereg/trcreg.cpp
diff --git a/samples/tracereg/trcreg.rc b/ext/detours/samples/tracereg/trcreg.rc
index 37adf3c..37adf3c 100644
--- a/samples/tracereg/trcreg.rc
+++ b/ext/detours/samples/tracereg/trcreg.rc
diff --git a/samples/traceser/Makefile b/ext/detours/samples/traceser/Makefile
index 0e29f0f..0e29f0f 100644
--- a/samples/traceser/Makefile
+++ b/ext/detours/samples/traceser/Makefile
diff --git a/samples/traceser/trcser.cpp b/ext/detours/samples/traceser/trcser.cpp
index b696fe6..b696fe6 100644
--- a/samples/traceser/trcser.cpp
+++ b/ext/detours/samples/traceser/trcser.cpp
diff --git a/samples/traceser/trcser.rc b/ext/detours/samples/traceser/trcser.rc
index 78f9b0e..78f9b0e 100644
--- a/samples/traceser/trcser.rc
+++ b/ext/detours/samples/traceser/trcser.rc
diff --git a/samples/tracessl/Makefile b/ext/detours/samples/tracessl/Makefile
index 8019256..8019256 100644
--- a/samples/tracessl/Makefile
+++ b/ext/detours/samples/tracessl/Makefile
diff --git a/samples/tracessl/trcssl.cpp b/ext/detours/samples/tracessl/trcssl.cpp
index ffc4439..ffc4439 100644
--- a/samples/tracessl/trcssl.cpp
+++ b/ext/detours/samples/tracessl/trcssl.cpp
diff --git a/samples/tracessl/trcssl.rc b/ext/detours/samples/tracessl/trcssl.rc
index 1e52e48..1e52e48 100644
--- a/samples/tracessl/trcssl.rc
+++ b/ext/detours/samples/tracessl/trcssl.rc
diff --git a/samples/tracetcp/Makefile b/ext/detours/samples/tracetcp/Makefile
index 61caaaa..61caaaa 100644
--- a/samples/tracetcp/Makefile
+++ b/ext/detours/samples/tracetcp/Makefile
diff --git a/samples/tracetcp/trctcp.cpp b/ext/detours/samples/tracetcp/trctcp.cpp
index 9f2a879..9f2a879 100644
--- a/samples/tracetcp/trctcp.cpp
+++ b/ext/detours/samples/tracetcp/trctcp.cpp
diff --git a/samples/tracetcp/trctcp.rc b/ext/detours/samples/tracetcp/trctcp.rc
index b3c6af5..b3c6af5 100644
--- a/samples/tracetcp/trctcp.rc
+++ b/ext/detours/samples/tracetcp/trctcp.rc
diff --git a/samples/tryman/Makefile b/ext/detours/samples/tryman/Makefile
index 62d1582..62d1582 100644
--- a/samples/tryman/Makefile
+++ b/ext/detours/samples/tryman/Makefile
diff --git a/samples/tryman/managed.cs b/ext/detours/samples/tryman/managed.cs
index cf8481d..cf8481d 100644
--- a/samples/tryman/managed.cs
+++ b/ext/detours/samples/tryman/managed.cs
diff --git a/samples/tryman/size.cpp b/ext/detours/samples/tryman/size.cpp
index f026750..f026750 100644
--- a/samples/tryman/size.cpp
+++ b/ext/detours/samples/tryman/size.cpp
diff --git a/samples/tryman/tryman.cpp b/ext/detours/samples/tryman/tryman.cpp
index 19a159b..19a159b 100644
--- a/samples/tryman/tryman.cpp
+++ b/ext/detours/samples/tryman/tryman.cpp
diff --git a/samples/tryman/tstman.cpp b/ext/detours/samples/tryman/tstman.cpp
index 0ae169b..0ae169b 100644
--- a/samples/tryman/tstman.cpp
+++ b/ext/detours/samples/tryman/tstman.cpp
diff --git a/samples/tryman/tstman.rc b/ext/detours/samples/tryman/tstman.rc
index 7380844..7380844 100644
--- a/samples/tryman/tstman.rc
+++ b/ext/detours/samples/tryman/tstman.rc
diff --git a/samples/withdll/Makefile b/ext/detours/samples/withdll/Makefile
index cafca4f..cafca4f 100644
--- a/samples/withdll/Makefile
+++ b/ext/detours/samples/withdll/Makefile
diff --git a/samples/withdll/withdll.cpp b/ext/detours/samples/withdll/withdll.cpp
index 4704573..4704573 100644
--- a/samples/withdll/withdll.cpp
+++ b/ext/detours/samples/withdll/withdll.cpp
diff --git a/src/Makefile b/ext/detours/src/Makefile
index 4d8fe74..4d8fe74 100644
--- a/src/Makefile
+++ b/ext/detours/src/Makefile
diff --git a/src/creatwth.cpp b/ext/detours/src/creatwth.cpp
index f7b51f4..f7b51f4 100644
--- a/src/creatwth.cpp
+++ b/ext/detours/src/creatwth.cpp
diff --git a/src/detours.cpp b/ext/detours/src/detours.cpp
index 34f2458..34f2458 100644
--- a/src/detours.cpp
+++ b/ext/detours/src/detours.cpp
diff --git a/src/detours.h b/ext/detours/src/detours.h
index c08b6f1..c08b6f1 100644
--- a/src/detours.h
+++ b/ext/detours/src/detours.h
diff --git a/src/detver.h b/ext/detours/src/detver.h
index 3d4f544..3d4f544 100644
--- a/src/detver.h
+++ b/ext/detours/src/detver.h
diff --git a/src/disasm.cpp b/ext/detours/src/disasm.cpp
index c12c1c1..c12c1c1 100644
--- a/src/disasm.cpp
+++ b/ext/detours/src/disasm.cpp
diff --git a/src/disolarm.cpp b/ext/detours/src/disolarm.cpp
index 57e3a2c..57e3a2c 100644
--- a/src/disolarm.cpp
+++ b/ext/detours/src/disolarm.cpp
diff --git a/src/disolarm64.cpp b/ext/detours/src/disolarm64.cpp
index f3a6aeb..f3a6aeb 100644
--- a/src/disolarm64.cpp
+++ b/ext/detours/src/disolarm64.cpp
diff --git a/src/disolia64.cpp b/ext/detours/src/disolia64.cpp
index 9dd2410..9dd2410 100644
--- a/src/disolia64.cpp
+++ b/ext/detours/src/disolia64.cpp
diff --git a/src/disolx64.cpp b/ext/detours/src/disolx64.cpp
index cd05a00..cd05a00 100644
--- a/src/disolx64.cpp
+++ b/ext/detours/src/disolx64.cpp
diff --git a/src/disolx86.cpp b/ext/detours/src/disolx86.cpp
index 91ff7d9..91ff7d9 100644
--- a/src/disolx86.cpp
+++ b/ext/detours/src/disolx86.cpp
diff --git a/src/image.cpp b/ext/detours/src/image.cpp
index 96282d2..96282d2 100644
--- a/src/image.cpp
+++ b/ext/detours/src/image.cpp
diff --git a/src/modules.cpp b/ext/detours/src/modules.cpp
index a797121..a797121 100644
--- a/src/modules.cpp
+++ b/ext/detours/src/modules.cpp
diff --git a/src/uimports.cpp b/ext/detours/src/uimports.cpp
index 5f454dd..5f454dd 100644
--- a/src/uimports.cpp
+++ b/ext/detours/src/uimports.cpp
diff --git a/system.mak b/ext/detours/system.mak
index 38f7090..38f7090 100644
--- a/system.mak
+++ b/ext/detours/system.mak
diff --git a/tests/Makefile b/ext/detours/tests/Makefile
index 1cc5749..1cc5749 100644
--- a/tests/Makefile
+++ b/ext/detours/tests/Makefile
diff --git a/tests/catch.hpp b/ext/detours/tests/catch.hpp
index cf1fae1..cf1fae1 100644
--- a/tests/catch.hpp
+++ b/ext/detours/tests/catch.hpp
diff --git a/tests/corruptor.cpp b/ext/detours/tests/corruptor.cpp
index e528629..e528629 100644
--- a/tests/corruptor.cpp
+++ b/ext/detours/tests/corruptor.cpp
diff --git a/tests/corruptor.h b/ext/detours/tests/corruptor.h
index f945287..f945287 100644
--- a/tests/corruptor.h
+++ b/ext/detours/tests/corruptor.h
diff --git a/tests/main.cpp b/ext/detours/tests/main.cpp
index 7d54470..7d54470 100644
--- a/tests/main.cpp
+++ b/ext/detours/tests/main.cpp
diff --git a/tests/test_image_api.cpp b/ext/detours/tests/test_image_api.cpp
index 37d7f0d..37d7f0d 100644
--- a/tests/test_image_api.cpp
+++ b/ext/detours/tests/test_image_api.cpp
diff --git a/tests/test_module_api.cpp b/ext/detours/tests/test_module_api.cpp
index f8ba304..f8ba304 100644
--- a/tests/test_module_api.cpp
+++ b/ext/detours/tests/test_module_api.cpp
diff --git a/vc/Detours.sln b/ext/detours/vc/Detours.sln
index 2bd5347..2bd5347 100644
--- a/vc/Detours.sln
+++ b/ext/detours/vc/Detours.sln
diff --git a/vc/Detours.vcxproj b/ext/detours/vc/Detours.vcxproj
index bc41223..bc41223 100644
--- a/vc/Detours.vcxproj
+++ b/ext/detours/vc/Detours.vcxproj
diff --git a/vc/Detours.vcxproj.filters b/ext/detours/vc/Detours.vcxproj.filters
index a6e401b..a6e401b 100644
--- a/vc/Detours.vcxproj.filters
+++ b/ext/detours/vc/Detours.vcxproj.filters
diff --git a/ext/spirv-headers b/ext/spirv-headers
new file mode 160000
+Subproject 308bd07424350a6000f35a77b5f85cd4f3da319
diff --git a/ext/spirv-tools b/ext/spirv-tools
new file mode 160000
+Subproject e128ab0d624ce7beb08eb9656bb260c597a46d0
diff --git a/level_zero-sys/Cargo.toml b/level_zero-sys/Cargo.toml
new file mode 100644
index 0000000..7f8b497
--- /dev/null
+++ b/level_zero-sys/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "level_zero-sys"
+version = "1.0.4"
+authors = ["Andrzej Janik <[email protected]>"]
+edition = "2018"
+links = "ze_loader"
+
+[lib] \ No newline at end of file
diff --git a/level_zero-sys/README b/level_zero-sys/README
new file mode 100644
index 0000000..ff5978a
--- /dev/null
+++ b/level_zero-sys/README
@@ -0,0 +1,4 @@
+sed 's/^typedef uint32_t ze_.*flags_t;$//g' /usr/local/include/level_zero/ze_api.h > ze_api.h
+sed -i -r 's/ze_(.*)_flag_t/ze_\1_flags_t/g' ze_api.h
+bindgen --size_t-is-usize --default-enum-style=newtype --bitfield-enum ".*flags_t" --whitelist-function "ze.*" ze_api.h -o ze_api.rs
+sed -i 's/pub struct _ze_result_t/#[must_use]\npub struct _ze_result_t/g' ze_api.rs \ No newline at end of file
diff --git a/level_zero-sys/build.rs b/level_zero-sys/build.rs
new file mode 100644
index 0000000..4a638ec
--- /dev/null
+++ b/level_zero-sys/build.rs
@@ -0,0 +1,18 @@
+use env::VarError;
+use std::{env, path::PathBuf};
+
+fn main() -> Result<(), VarError> {
+ println!("cargo:rustc-link-lib=dylib=ze_loader");
+ if env::var("CARGO_CFG_WINDOWS").is_ok() {
+ let env = env::var("CARGO_CFG_TARGET_ENV")?;
+ if env == "gnu" {
+ println!("cargo:rustc-link-search=native=C:\\Windows\\System32");
+ } else {
+ let mut path = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?);
+ path.push("src");
+ println!("cargo:rustc-link-search=native={}", path.display());
+ };
+ }
+ println!("cargo:rerun-if-changed=build.rs");
+ Ok(())
+}
diff --git a/level_zero-sys/src/lib.rs b/level_zero-sys/src/lib.rs
new file mode 100644
index 0000000..f7a7feb
--- /dev/null
+++ b/level_zero-sys/src/lib.rs
@@ -0,0 +1,3 @@
+#![allow(warnings)]
+pub mod ze_api;
+pub use ze_api::*; \ No newline at end of file
diff --git a/level_zero-sys/src/ze_api.rs b/level_zero-sys/src/ze_api.rs
new file mode 100644
index 0000000..e64988a
--- /dev/null
+++ b/level_zero-sys/src/ze_api.rs
@@ -0,0 +1,9948 @@
+/* automatically generated by rust-bindgen 0.54.1 */
+
+pub type __uint8_t = ::std::os::raw::c_uchar;
+pub type __uint32_t = ::std::os::raw::c_uint;
+pub type __uint64_t = ::std::os::raw::c_ulong;
+#[doc = ""]
+#[doc = " @brief compiler-independent type"]
+pub type ze_bool_t = u8;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_driver_handle_t {
+ _unused: [u8; 0],
+}
+#[doc = ""]
+#[doc = " @brief Handle of a driver instance"]
+pub type ze_driver_handle_t = *mut _ze_driver_handle_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_device_handle_t {
+ _unused: [u8; 0],
+}
+#[doc = ""]
+#[doc = " @brief Handle of driver's device object"]
+pub type ze_device_handle_t = *mut _ze_device_handle_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_context_handle_t {
+ _unused: [u8; 0],
+}
+#[doc = ""]
+#[doc = " @brief Handle of driver's context object"]
+pub type ze_context_handle_t = *mut _ze_context_handle_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_command_queue_handle_t {
+ _unused: [u8; 0],
+}
+#[doc = ""]
+#[doc = " @brief Handle of driver's command queue object"]
+pub type ze_command_queue_handle_t = *mut _ze_command_queue_handle_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_command_list_handle_t {
+ _unused: [u8; 0],
+}
+#[doc = ""]
+#[doc = " @brief Handle of driver's command list object"]
+pub type ze_command_list_handle_t = *mut _ze_command_list_handle_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_fence_handle_t {
+ _unused: [u8; 0],
+}
+#[doc = ""]
+#[doc = " @brief Handle of driver's fence object"]
+pub type ze_fence_handle_t = *mut _ze_fence_handle_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_event_pool_handle_t {
+ _unused: [u8; 0],
+}
+#[doc = ""]
+#[doc = " @brief Handle of driver's event pool object"]
+pub type ze_event_pool_handle_t = *mut _ze_event_pool_handle_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_event_handle_t {
+ _unused: [u8; 0],
+}
+#[doc = ""]
+#[doc = " @brief Handle of driver's event object"]
+pub type ze_event_handle_t = *mut _ze_event_handle_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_image_handle_t {
+ _unused: [u8; 0],
+}
+#[doc = ""]
+#[doc = " @brief Handle of driver's image object"]
+pub type ze_image_handle_t = *mut _ze_image_handle_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_module_handle_t {
+ _unused: [u8; 0],
+}
+#[doc = ""]
+#[doc = " @brief Handle of driver's module object"]
+pub type ze_module_handle_t = *mut _ze_module_handle_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_module_build_log_handle_t {
+ _unused: [u8; 0],
+}
+#[doc = ""]
+#[doc = " @brief Handle of module's build log object"]
+pub type ze_module_build_log_handle_t = *mut _ze_module_build_log_handle_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_kernel_handle_t {
+ _unused: [u8; 0],
+}
+#[doc = ""]
+#[doc = " @brief Handle of driver's kernel object"]
+pub type ze_kernel_handle_t = *mut _ze_kernel_handle_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_sampler_handle_t {
+ _unused: [u8; 0],
+}
+#[doc = ""]
+#[doc = " @brief Handle of driver's sampler object"]
+pub type ze_sampler_handle_t = *mut _ze_sampler_handle_t;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_physical_mem_handle_t {
+ _unused: [u8; 0],
+}
+#[doc = ""]
+#[doc = " @brief Handle of physical memory object"]
+pub type ze_physical_mem_handle_t = *mut _ze_physical_mem_handle_t;
+#[doc = ""]
+#[doc = " @brief IPC handle to a memory allocation"]
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct _ze_ipc_mem_handle_t {
+ #[doc = "< [out] Opaque data representing an IPC handle"]
+ pub data: [::std::os::raw::c_char; 64usize],
+}
+#[test]
+fn bindgen_test_layout__ze_ipc_mem_handle_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_ipc_mem_handle_t>(),
+ 64usize,
+ concat!("Size of: ", stringify!(_ze_ipc_mem_handle_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_ipc_mem_handle_t>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(_ze_ipc_mem_handle_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_ipc_mem_handle_t>())).data as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_ipc_mem_handle_t),
+ "::",
+ stringify!(data)
+ )
+ );
+}
+#[doc = ""]
+#[doc = " @brief IPC handle to a memory allocation"]
+pub type ze_ipc_mem_handle_t = _ze_ipc_mem_handle_t;
+#[doc = ""]
+#[doc = " @brief IPC handle to a event pool allocation"]
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct _ze_ipc_event_pool_handle_t {
+ #[doc = "< [out] Opaque data representing an IPC handle"]
+ pub data: [::std::os::raw::c_char; 64usize],
+}
+#[test]
+fn bindgen_test_layout__ze_ipc_event_pool_handle_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_ipc_event_pool_handle_t>(),
+ 64usize,
+ concat!("Size of: ", stringify!(_ze_ipc_event_pool_handle_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_ipc_event_pool_handle_t>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(_ze_ipc_event_pool_handle_t))
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_ipc_event_pool_handle_t>())).data as *const _ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_ipc_event_pool_handle_t),
+ "::",
+ stringify!(data)
+ )
+ );
+}
+#[doc = ""]
+#[doc = " @brief IPC handle to a event pool allocation"]
+pub type ze_ipc_event_pool_handle_t = _ze_ipc_event_pool_handle_t;
+impl _ze_result_t {
+ #[doc = "< [Core] success"]
+ pub const ZE_RESULT_SUCCESS: _ze_result_t = _ze_result_t(0);
+}
+impl _ze_result_t {
+ #[doc = "< [Core] synchronization primitive not signaled"]
+ pub const ZE_RESULT_NOT_READY: _ze_result_t = _ze_result_t(1);
+}
+impl _ze_result_t {
+ #[doc = "< [Core] device hung, reset, was removed, or driver update occurred"]
+ pub const ZE_RESULT_ERROR_DEVICE_LOST: _ze_result_t = _ze_result_t(1879048193);
+}
+impl _ze_result_t {
+ #[doc = "< [Core] insufficient host memory to satisfy call"]
+ pub const ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY: _ze_result_t = _ze_result_t(1879048194);
+}
+impl _ze_result_t {
+ #[doc = "< [Core] insufficient device memory to satisfy call"]
+ pub const ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY: _ze_result_t = _ze_result_t(1879048195);
+}
+impl _ze_result_t {
+ #[doc = "< [Core] error occurred when building module, see build log for details"]
+ pub const ZE_RESULT_ERROR_MODULE_BUILD_FAILURE: _ze_result_t = _ze_result_t(1879048196);
+}
+impl _ze_result_t {
+ #[doc = "< [Core] error occurred when linking modules, see build log for details"]
+ pub const ZE_RESULT_ERROR_MODULE_LINK_FAILURE: _ze_result_t = _ze_result_t(1879048197);
+}
+impl _ze_result_t {
+ #[doc = "< [Sysman] access denied due to permission level"]
+ pub const ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS: _ze_result_t = _ze_result_t(1879113728);
+}
+impl _ze_result_t {
+ #[doc = "< [Sysman] resource already in use and simultaneous access not allowed"]
+ #[doc = "< or resource was removed"]
+ pub const ZE_RESULT_ERROR_NOT_AVAILABLE: _ze_result_t = _ze_result_t(1879113729);
+}
+impl _ze_result_t {
+ #[doc = "< [Tools] external required dependency is unavailable or missing"]
+ pub const ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE: _ze_result_t = _ze_result_t(1879179264);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] driver is not initialized"]
+ pub const ZE_RESULT_ERROR_UNINITIALIZED: _ze_result_t = _ze_result_t(2013265921);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] generic error code for unsupported versions"]
+ pub const ZE_RESULT_ERROR_UNSUPPORTED_VERSION: _ze_result_t = _ze_result_t(2013265922);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] generic error code for unsupported features"]
+ pub const ZE_RESULT_ERROR_UNSUPPORTED_FEATURE: _ze_result_t = _ze_result_t(2013265923);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] generic error code for invalid arguments"]
+ pub const ZE_RESULT_ERROR_INVALID_ARGUMENT: _ze_result_t = _ze_result_t(2013265924);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] handle argument is not valid"]
+ pub const ZE_RESULT_ERROR_INVALID_NULL_HANDLE: _ze_result_t = _ze_result_t(2013265925);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] object pointed to by handle still in-use by device"]
+ pub const ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE: _ze_result_t = _ze_result_t(2013265926);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] pointer argument may not be nullptr"]
+ pub const ZE_RESULT_ERROR_INVALID_NULL_POINTER: _ze_result_t = _ze_result_t(2013265927);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] size argument is invalid (e.g., must not be zero)"]
+ pub const ZE_RESULT_ERROR_INVALID_SIZE: _ze_result_t = _ze_result_t(2013265928);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] size argument is not supported by the device (e.g., too"]
+ #[doc = "< large)"]
+ pub const ZE_RESULT_ERROR_UNSUPPORTED_SIZE: _ze_result_t = _ze_result_t(2013265929);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] alignment argument is not supported by the device (e.g.,"]
+ #[doc = "< too small)"]
+ pub const ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT: _ze_result_t = _ze_result_t(2013265930);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] synchronization object in invalid state"]
+ pub const ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT: _ze_result_t =
+ _ze_result_t(2013265931);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] enumerator argument is not valid"]
+ pub const ZE_RESULT_ERROR_INVALID_ENUMERATION: _ze_result_t = _ze_result_t(2013265932);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] enumerator argument is not supported by the device"]
+ pub const ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION: _ze_result_t = _ze_result_t(2013265933);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] image format is not supported by the device"]
+ pub const ZE_RESULT_ERROR_UNSUPPORTED_IMAGE_FORMAT: _ze_result_t = _ze_result_t(2013265934);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] native binary is not supported by the device"]
+ pub const ZE_RESULT_ERROR_INVALID_NATIVE_BINARY: _ze_result_t = _ze_result_t(2013265935);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] global variable is not found in the module"]
+ pub const ZE_RESULT_ERROR_INVALID_GLOBAL_NAME: _ze_result_t = _ze_result_t(2013265936);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] kernel name is not found in the module"]
+ pub const ZE_RESULT_ERROR_INVALID_KERNEL_NAME: _ze_result_t = _ze_result_t(2013265937);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] function name is not found in the module"]
+ pub const ZE_RESULT_ERROR_INVALID_FUNCTION_NAME: _ze_result_t = _ze_result_t(2013265938);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] group size dimension is not valid for the kernel or"]
+ #[doc = "< device"]
+ pub const ZE_RESULT_ERROR_INVALID_GROUP_SIZE_DIMENSION: _ze_result_t = _ze_result_t(2013265939);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] global width dimension is not valid for the kernel or"]
+ #[doc = "< device"]
+ pub const ZE_RESULT_ERROR_INVALID_GLOBAL_WIDTH_DIMENSION: _ze_result_t =
+ _ze_result_t(2013265940);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] kernel argument index is not valid for kernel"]
+ pub const ZE_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_INDEX: _ze_result_t =
+ _ze_result_t(2013265941);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] kernel argument size does not match kernel"]
+ pub const ZE_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_SIZE: _ze_result_t = _ze_result_t(2013265942);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] value of kernel attribute is not valid for the kernel or"]
+ #[doc = "< device"]
+ pub const ZE_RESULT_ERROR_INVALID_KERNEL_ATTRIBUTE_VALUE: _ze_result_t =
+ _ze_result_t(2013265943);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] module with imports needs to be linked before kernels can"]
+ #[doc = "< be created from it."]
+ pub const ZE_RESULT_ERROR_INVALID_MODULE_UNLINKED: _ze_result_t = _ze_result_t(2013265944);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] command list type does not match command queue type"]
+ pub const ZE_RESULT_ERROR_INVALID_COMMAND_LIST_TYPE: _ze_result_t = _ze_result_t(2013265945);
+}
+impl _ze_result_t {
+ #[doc = "< [Validation] copy operations do not support overlapping regions of"]
+ #[doc = "< memory"]
+ pub const ZE_RESULT_ERROR_OVERLAPPING_REGIONS: _ze_result_t = _ze_result_t(2013265946);
+}
+impl _ze_result_t {
+ #[doc = "< [Core] unknown or internal error"]
+ pub const ZE_RESULT_ERROR_UNKNOWN: _ze_result_t = _ze_result_t(2147483646);
+}
+impl _ze_result_t {
+ pub const ZE_RESULT_FORCE_UINT32: _ze_result_t = _ze_result_t(2147483647);
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Defines Return/Error codes"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+#[must_use]
+pub struct _ze_result_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Defines Return/Error codes"]
+pub use self::_ze_result_t as ze_result_t;
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_driver_properties_t"]
+ pub const ZE_STRUCTURE_TYPE_DRIVER_PROPERTIES: _ze_structure_type_t = _ze_structure_type_t(1);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_driver_ipc_properties_t"]
+ pub const ZE_STRUCTURE_TYPE_DRIVER_IPC_PROPERTIES: _ze_structure_type_t =
+ _ze_structure_type_t(2);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_device_properties_t"]
+ pub const ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES: _ze_structure_type_t = _ze_structure_type_t(3);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_device_compute_properties_t"]
+ pub const ZE_STRUCTURE_TYPE_DEVICE_COMPUTE_PROPERTIES: _ze_structure_type_t =
+ _ze_structure_type_t(4);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_device_module_properties_t"]
+ pub const ZE_STRUCTURE_TYPE_DEVICE_MODULE_PROPERTIES: _ze_structure_type_t =
+ _ze_structure_type_t(5);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_command_queue_group_properties_t"]
+ pub const ZE_STRUCTURE_TYPE_COMMAND_QUEUE_GROUP_PROPERTIES: _ze_structure_type_t =
+ _ze_structure_type_t(6);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_device_memory_properties_t"]
+ pub const ZE_STRUCTURE_TYPE_DEVICE_MEMORY_PROPERTIES: _ze_structure_type_t =
+ _ze_structure_type_t(7);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_device_memory_access_properties_t"]
+ pub const ZE_STRUCTURE_TYPE_DEVICE_MEMORY_ACCESS_PROPERTIES: _ze_structure_type_t =
+ _ze_structure_type_t(8);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_device_cache_properties_t"]
+ pub const ZE_STRUCTURE_TYPE_DEVICE_CACHE_PROPERTIES: _ze_structure_type_t =
+ _ze_structure_type_t(9);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_device_image_properties_t"]
+ pub const ZE_STRUCTURE_TYPE_DEVICE_IMAGE_PROPERTIES: _ze_structure_type_t =
+ _ze_structure_type_t(10);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_device_p2p_properties_t"]
+ pub const ZE_STRUCTURE_TYPE_DEVICE_P2P_PROPERTIES: _ze_structure_type_t =
+ _ze_structure_type_t(11);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_device_external_memory_properties_t"]
+ pub const ZE_STRUCTURE_TYPE_DEVICE_EXTERNAL_MEMORY_PROPERTIES: _ze_structure_type_t =
+ _ze_structure_type_t(12);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_context_desc_t"]
+ pub const ZE_STRUCTURE_TYPE_CONTEXT_DESC: _ze_structure_type_t = _ze_structure_type_t(13);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_command_queue_desc_t"]
+ pub const ZE_STRUCTURE_TYPE_COMMAND_QUEUE_DESC: _ze_structure_type_t = _ze_structure_type_t(14);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_command_list_desc_t"]
+ pub const ZE_STRUCTURE_TYPE_COMMAND_LIST_DESC: _ze_structure_type_t = _ze_structure_type_t(15);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_event_pool_desc_t"]
+ pub const ZE_STRUCTURE_TYPE_EVENT_POOL_DESC: _ze_structure_type_t = _ze_structure_type_t(16);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_event_desc_t"]
+ pub const ZE_STRUCTURE_TYPE_EVENT_DESC: _ze_structure_type_t = _ze_structure_type_t(17);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_fence_desc_t"]
+ pub const ZE_STRUCTURE_TYPE_FENCE_DESC: _ze_structure_type_t = _ze_structure_type_t(18);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_image_desc_t"]
+ pub const ZE_STRUCTURE_TYPE_IMAGE_DESC: _ze_structure_type_t = _ze_structure_type_t(19);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_image_properties_t"]
+ pub const ZE_STRUCTURE_TYPE_IMAGE_PROPERTIES: _ze_structure_type_t = _ze_structure_type_t(20);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_device_mem_alloc_desc_t"]
+ pub const ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC: _ze_structure_type_t =
+ _ze_structure_type_t(21);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_host_mem_alloc_desc_t"]
+ pub const ZE_STRUCTURE_TYPE_HOST_MEM_ALLOC_DESC: _ze_structure_type_t =
+ _ze_structure_type_t(22);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_memory_allocation_properties_t"]
+ pub const ZE_STRUCTURE_TYPE_MEMORY_ALLOCATION_PROPERTIES: _ze_structure_type_t =
+ _ze_structure_type_t(23);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_external_memory_export_desc_t"]
+ pub const ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_DESC: _ze_structure_type_t =
+ _ze_structure_type_t(24);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_external_memory_import_fd_t"]
+ pub const ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_FD: _ze_structure_type_t =
+ _ze_structure_type_t(25);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_external_memory_export_fd_t"]
+ pub const ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_FD: _ze_structure_type_t =
+ _ze_structure_type_t(26);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_module_desc_t"]
+ pub const ZE_STRUCTURE_TYPE_MODULE_DESC: _ze_structure_type_t = _ze_structure_type_t(27);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_module_properties_t"]
+ pub const ZE_STRUCTURE_TYPE_MODULE_PROPERTIES: _ze_structure_type_t = _ze_structure_type_t(28);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_kernel_desc_t"]
+ pub const ZE_STRUCTURE_TYPE_KERNEL_DESC: _ze_structure_type_t = _ze_structure_type_t(29);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_kernel_properties_t"]
+ pub const ZE_STRUCTURE_TYPE_KERNEL_PROPERTIES: _ze_structure_type_t = _ze_structure_type_t(30);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_sampler_desc_t"]
+ pub const ZE_STRUCTURE_TYPE_SAMPLER_DESC: _ze_structure_type_t = _ze_structure_type_t(31);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_physical_mem_desc_t"]
+ pub const ZE_STRUCTURE_TYPE_PHYSICAL_MEM_DESC: _ze_structure_type_t = _ze_structure_type_t(32);
+}
+impl _ze_structure_type_t {
+ #[doc = "< ::ze_raytracing_mem_alloc_ext_desc_t"]
+ pub const ZE_STRUCTURE_TYPE_RAYTRACING_MEM_ALLOC_EXT_DESC: _ze_structure_type_t =
+ _ze_structure_type_t(65537);
+}
+impl _ze_structure_type_t {
+ pub const ZE_STRUCTURE_TYPE_FORCE_UINT32: _ze_structure_type_t =
+ _ze_structure_type_t(2147483647);
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Defines structure types"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_structure_type_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Defines structure types"]
+pub use self::_ze_structure_type_t as ze_structure_type_t;
+impl _ze_external_memory_type_flags_t {
+ #[doc = "< an opaque POSIX file descriptor handle"]
+ pub const ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_FD: _ze_external_memory_type_flags_t =
+ _ze_external_memory_type_flags_t(1);
+}
+impl _ze_external_memory_type_flags_t {
+ #[doc = "< a file descriptor handle for a Linux dma_buf"]
+ pub const ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF: _ze_external_memory_type_flags_t =
+ _ze_external_memory_type_flags_t(2);
+}
+impl _ze_external_memory_type_flags_t {
+ pub const ZE_EXTERNAL_MEMORY_TYPE_FLAG_FORCE_UINT32: _ze_external_memory_type_flags_t =
+ _ze_external_memory_type_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_external_memory_type_flags_t> for _ze_external_memory_type_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_external_memory_type_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_external_memory_type_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_external_memory_type_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_external_memory_type_flags_t> for _ze_external_memory_type_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_external_memory_type_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_external_memory_type_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_external_memory_type_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief External memory type flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_external_memory_type_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief External memory type flags"]
+pub use self::_ze_external_memory_type_flags_t as ze_external_memory_type_flags_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_driver_uuid_t"]
+pub type ze_driver_uuid_t = _ze_driver_uuid_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_driver_properties_t"]
+pub type ze_driver_properties_t = _ze_driver_properties_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_driver_ipc_properties_t"]
+pub type ze_driver_ipc_properties_t = _ze_driver_ipc_properties_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_driver_extension_properties_t"]
+pub type ze_driver_extension_properties_t = _ze_driver_extension_properties_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_device_uuid_t"]
+pub type ze_device_uuid_t = _ze_device_uuid_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_device_properties_t"]
+pub type ze_device_properties_t = _ze_device_properties_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_device_compute_properties_t"]
+pub type ze_device_compute_properties_t = _ze_device_compute_properties_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_native_kernel_uuid_t"]
+pub type ze_native_kernel_uuid_t = _ze_native_kernel_uuid_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_device_module_properties_t"]
+pub type ze_device_module_properties_t = _ze_device_module_properties_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_command_queue_group_properties_t"]
+pub type ze_command_queue_group_properties_t = _ze_command_queue_group_properties_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_device_memory_properties_t"]
+pub type ze_device_memory_properties_t = _ze_device_memory_properties_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_device_memory_access_properties_t"]
+pub type ze_device_memory_access_properties_t = _ze_device_memory_access_properties_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_device_cache_properties_t"]
+pub type ze_device_cache_properties_t = _ze_device_cache_properties_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_device_image_properties_t"]
+pub type ze_device_image_properties_t = _ze_device_image_properties_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_device_external_memory_properties_t"]
+pub type ze_device_external_memory_properties_t = _ze_device_external_memory_properties_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_device_p2p_properties_t"]
+pub type ze_device_p2p_properties_t = _ze_device_p2p_properties_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_context_desc_t"]
+pub type ze_context_desc_t = _ze_context_desc_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_command_queue_desc_t"]
+pub type ze_command_queue_desc_t = _ze_command_queue_desc_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_command_list_desc_t"]
+pub type ze_command_list_desc_t = _ze_command_list_desc_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_copy_region_t"]
+pub type ze_copy_region_t = _ze_copy_region_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_image_region_t"]
+pub type ze_image_region_t = _ze_image_region_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_event_pool_desc_t"]
+pub type ze_event_pool_desc_t = _ze_event_pool_desc_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_event_desc_t"]
+pub type ze_event_desc_t = _ze_event_desc_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_kernel_timestamp_data_t"]
+pub type ze_kernel_timestamp_data_t = _ze_kernel_timestamp_data_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_kernel_timestamp_result_t"]
+pub type ze_kernel_timestamp_result_t = _ze_kernel_timestamp_result_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_fence_desc_t"]
+pub type ze_fence_desc_t = _ze_fence_desc_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_image_format_t"]
+pub type ze_image_format_t = _ze_image_format_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_image_desc_t"]
+pub type ze_image_desc_t = _ze_image_desc_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_image_properties_t"]
+pub type ze_image_properties_t = _ze_image_properties_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_device_mem_alloc_desc_t"]
+pub type ze_device_mem_alloc_desc_t = _ze_device_mem_alloc_desc_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_host_mem_alloc_desc_t"]
+pub type ze_host_mem_alloc_desc_t = _ze_host_mem_alloc_desc_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_memory_allocation_properties_t"]
+pub type ze_memory_allocation_properties_t = _ze_memory_allocation_properties_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_module_constants_t"]
+pub type ze_module_constants_t = _ze_module_constants_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_module_desc_t"]
+pub type ze_module_desc_t = _ze_module_desc_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_module_properties_t"]
+pub type ze_module_properties_t = _ze_module_properties_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_kernel_desc_t"]
+pub type ze_kernel_desc_t = _ze_kernel_desc_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_kernel_uuid_t"]
+pub type ze_kernel_uuid_t = _ze_kernel_uuid_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_kernel_properties_t"]
+pub type ze_kernel_properties_t = _ze_kernel_properties_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_group_count_t"]
+pub type ze_group_count_t = _ze_group_count_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_sampler_desc_t"]
+pub type ze_sampler_desc_t = _ze_sampler_desc_t;
+#[doc = ""]
+#[doc = " @brief Forward-declare ze_physical_mem_desc_t"]
+pub type ze_physical_mem_desc_t = _ze_physical_mem_desc_t;
+impl _ze_init_flags_t {
+ #[doc = "< only initialize GPU drivers"]
+ pub const ZE_INIT_FLAG_GPU_ONLY: _ze_init_flags_t = _ze_init_flags_t(1);
+}
+impl _ze_init_flags_t {
+ pub const ZE_INIT_FLAG_FORCE_UINT32: _ze_init_flags_t = _ze_init_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_init_flags_t> for _ze_init_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_init_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_init_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_init_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_init_flags_t> for _ze_init_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_init_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_init_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_init_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported initialization flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_init_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported initialization flags"]
+pub use self::_ze_init_flags_t as ze_init_flags_t;
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Initialize the 'oneAPI' driver(s)"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - This function must be called before any other API function."]
+ #[doc = " - If this function is not called then all other functions will return"]
+ #[doc = " ::ZE_RESULT_ERROR_UNINITIALIZED."]
+ #[doc = " - Only one instance of each driver will be initialized per process."]
+ #[doc = " - This function is thread-safe for scenarios where multiple libraries"]
+ #[doc = " may initialize the driver(s) simultaneously."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `0x1 < flags`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ pub fn zeInit(flags: ze_init_flags_t) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves driver instances"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - A driver represents a collection of physical devices."]
+ #[doc = " - Multiple calls to this function will return identical driver handles,"]
+ #[doc = " in the same order."]
+ #[doc = " - The application may pass nullptr for pDrivers when only querying the"]
+ #[doc = " number of drivers."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - clGetPlatformIDs"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pCount`"]
+ pub fn zeDriverGet(pCount: *mut u32, phDrivers: *mut ze_driver_handle_t) -> ze_result_t;
+}
+impl _ze_api_version_t {
+ #[doc = "< version 1.0"]
+ pub const ZE_API_VERSION_1_0: _ze_api_version_t = _ze_api_version_t(65536);
+}
+impl _ze_api_version_t {
+ #[doc = "< latest known version"]
+ pub const ZE_API_VERSION_CURRENT: _ze_api_version_t = _ze_api_version_t(65536);
+}
+impl _ze_api_version_t {
+ pub const ZE_API_VERSION_FORCE_UINT32: _ze_api_version_t = _ze_api_version_t(2147483647);
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported API versions"]
+#[doc = ""]
+#[doc = " @details"]
+#[doc = " - API versions contain major and minor attributes, use"]
+#[doc = " ::ZE_MAJOR_VERSION and ::ZE_MINOR_VERSION"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_api_version_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported API versions"]
+#[doc = ""]
+#[doc = " @details"]
+#[doc = " - API versions contain major and minor attributes, use"]
+#[doc = " ::ZE_MAJOR_VERSION and ::ZE_MINOR_VERSION"]
+pub use self::_ze_api_version_t as ze_api_version_t;
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Returns the API version supported by the specified driver"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDriver`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == version`"]
+ pub fn zeDriverGetApiVersion(
+ hDriver: ze_driver_handle_t,
+ version: *mut ze_api_version_t,
+ ) -> ze_result_t;
+}
+#[doc = ""]
+#[doc = " @brief Driver universal unique id (UUID)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_driver_uuid_t {
+ #[doc = "< [out] opaque data representing a driver UUID"]
+ pub id: [u8; 16usize],
+}
+#[test]
+fn bindgen_test_layout__ze_driver_uuid_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_driver_uuid_t>(),
+ 16usize,
+ concat!("Size of: ", stringify!(_ze_driver_uuid_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_driver_uuid_t>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(_ze_driver_uuid_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_driver_uuid_t>())).id as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_driver_uuid_t),
+ "::",
+ stringify!(id)
+ )
+ );
+}
+#[doc = ""]
+#[doc = " @brief Driver properties queried using ::zeDriverGetProperties"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_driver_properties_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in,out][optional] pointer to extension-specific structure"]
+ pub pNext: *mut ::std::os::raw::c_void,
+ #[doc = "< [out] universal unique identifier."]
+ pub uuid: ze_driver_uuid_t,
+ #[doc = "< [out] driver version"]
+ #[doc = "< The driver version is a non-zero, monotonically increasing value where"]
+ #[doc = "< higher values always indicate a more recent version."]
+ pub driverVersion: u32,
+}
+#[test]
+fn bindgen_test_layout__ze_driver_properties_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_driver_properties_t>(),
+ 40usize,
+ concat!("Size of: ", stringify!(_ze_driver_properties_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_driver_properties_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_driver_properties_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_driver_properties_t>())).stype as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_driver_properties_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_driver_properties_t>())).pNext as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_driver_properties_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_driver_properties_t>())).uuid as *const _ as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_driver_properties_t),
+ "::",
+ stringify!(uuid)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_driver_properties_t>())).driverVersion as *const _ as usize
+ },
+ 32usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_driver_properties_t),
+ "::",
+ stringify!(driverVersion)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves properties of the driver."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - **clGetPlatformInfo**"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDriver`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pDriverProperties`"]
+ pub fn zeDriverGetProperties(
+ hDriver: ze_driver_handle_t,
+ pDriverProperties: *mut ze_driver_properties_t,
+ ) -> ze_result_t;
+}
+impl _ze_ipc_property_flags_t {
+ #[doc = "< Supports passing memory allocations between processes. See"]
+ #[doc = "< ::zeMemGetIpcHandle."]
+ pub const ZE_IPC_PROPERTY_FLAG_MEMORY: _ze_ipc_property_flags_t = _ze_ipc_property_flags_t(1);
+}
+impl _ze_ipc_property_flags_t {
+ #[doc = "< Supports passing event pools between processes. See"]
+ #[doc = "< ::zeEventPoolGetIpcHandle."]
+ pub const ZE_IPC_PROPERTY_FLAG_EVENT_POOL: _ze_ipc_property_flags_t =
+ _ze_ipc_property_flags_t(2);
+}
+impl _ze_ipc_property_flags_t {
+ pub const ZE_IPC_PROPERTY_FLAG_FORCE_UINT32: _ze_ipc_property_flags_t =
+ _ze_ipc_property_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_ipc_property_flags_t> for _ze_ipc_property_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_ipc_property_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_ipc_property_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_ipc_property_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_ipc_property_flags_t> for _ze_ipc_property_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_ipc_property_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_ipc_property_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_ipc_property_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported IPC property flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_ipc_property_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported IPC property flags"]
+pub use self::_ze_ipc_property_flags_t as ze_ipc_property_flags_t;
+#[doc = ""]
+#[doc = " @brief IPC properties queried using ::zeDriverGetIpcProperties"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_driver_ipc_properties_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in,out][optional] pointer to extension-specific structure"]
+ pub pNext: *mut ::std::os::raw::c_void,
+ #[doc = "< [out] 0 (none) or a valid combination of ::ze_ipc_property_flags_t"]
+ pub flags: ze_ipc_property_flags_t,
+}
+#[test]
+fn bindgen_test_layout__ze_driver_ipc_properties_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_driver_ipc_properties_t>(),
+ 24usize,
+ concat!("Size of: ", stringify!(_ze_driver_ipc_properties_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_driver_ipc_properties_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_driver_ipc_properties_t))
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_driver_ipc_properties_t>())).stype as *const _ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_driver_ipc_properties_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_driver_ipc_properties_t>())).pNext as *const _ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_driver_ipc_properties_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_driver_ipc_properties_t>())).flags as *const _ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_driver_ipc_properties_t),
+ "::",
+ stringify!(flags)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves IPC attributes of the driver"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDriver`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pIpcProperties`"]
+ pub fn zeDriverGetIpcProperties(
+ hDriver: ze_driver_handle_t,
+ pIpcProperties: *mut ze_driver_ipc_properties_t,
+ ) -> ze_result_t;
+}
+#[doc = ""]
+#[doc = " @brief Extension properties queried using ::zeDriverGetExtensionProperties"]
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct _ze_driver_extension_properties_t {
+ #[doc = "< [out] extension name"]
+ pub name: [::std::os::raw::c_char; 256usize],
+ #[doc = "< [out] extension version using ::ZE_MAKE_VERSION"]
+ pub version: u32,
+}
+#[test]
+fn bindgen_test_layout__ze_driver_extension_properties_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_driver_extension_properties_t>(),
+ 260usize,
+ concat!("Size of: ", stringify!(_ze_driver_extension_properties_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_driver_extension_properties_t>(),
+ 4usize,
+ concat!(
+ "Alignment of ",
+ stringify!(_ze_driver_extension_properties_t)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_driver_extension_properties_t>())).name as *const _ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_driver_extension_properties_t),
+ "::",
+ stringify!(name)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_driver_extension_properties_t>())).version as *const _
+ as usize
+ },
+ 256usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_driver_extension_properties_t),
+ "::",
+ stringify!(version)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves extension properties"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - **vkEnumerateInstanceExtensionProperties**"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDriver`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pCount`"]
+ pub fn zeDriverGetExtensionProperties(
+ hDriver: ze_driver_handle_t,
+ pCount: *mut u32,
+ pExtensionProperties: *mut ze_driver_extension_properties_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves devices within a driver"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Multiple calls to this function will return identical device handles,"]
+ #[doc = " in the same order."]
+ #[doc = " - The number and order of handles returned from this function is"]
+ #[doc = " affected by the ::ZE_AFFINITY_MASK and ::ZE_ENABLE_PCI_ID_DEVICE_ORDER"]
+ #[doc = " environment variables."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDriver`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pCount`"]
+ pub fn zeDeviceGet(
+ hDriver: ze_driver_handle_t,
+ pCount: *mut u32,
+ phDevices: *mut ze_device_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves a sub-device from a device"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Multiple calls to this function will return identical device handles,"]
+ #[doc = " in the same order."]
+ #[doc = " - The number of handles returned from this function is affected by the"]
+ #[doc = " ::ZE_AFFINITY_MASK environment variable."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - clCreateSubDevices"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pCount`"]
+ pub fn zeDeviceGetSubDevices(
+ hDevice: ze_device_handle_t,
+ pCount: *mut u32,
+ phSubdevices: *mut ze_device_handle_t,
+ ) -> ze_result_t;
+}
+impl _ze_device_type_t {
+ #[doc = "< Graphics Processing Unit"]
+ pub const ZE_DEVICE_TYPE_GPU: _ze_device_type_t = _ze_device_type_t(1);
+}
+impl _ze_device_type_t {
+ #[doc = "< Central Processing Unit"]
+ pub const ZE_DEVICE_TYPE_CPU: _ze_device_type_t = _ze_device_type_t(2);
+}
+impl _ze_device_type_t {
+ #[doc = "< Field Programmable Gate Array"]
+ pub const ZE_DEVICE_TYPE_FPGA: _ze_device_type_t = _ze_device_type_t(3);
+}
+impl _ze_device_type_t {
+ #[doc = "< Memory Copy Accelerator"]
+ pub const ZE_DEVICE_TYPE_MCA: _ze_device_type_t = _ze_device_type_t(4);
+}
+impl _ze_device_type_t {
+ pub const ZE_DEVICE_TYPE_FORCE_UINT32: _ze_device_type_t = _ze_device_type_t(2147483647);
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported device types"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_device_type_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported device types"]
+pub use self::_ze_device_type_t as ze_device_type_t;
+#[doc = ""]
+#[doc = " @brief Device universal unique id (UUID)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_device_uuid_t {
+ #[doc = "< [out] opaque data representing a device UUID"]
+ pub id: [u8; 16usize],
+}
+#[test]
+fn bindgen_test_layout__ze_device_uuid_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_device_uuid_t>(),
+ 16usize,
+ concat!("Size of: ", stringify!(_ze_device_uuid_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_device_uuid_t>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(_ze_device_uuid_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_device_uuid_t>())).id as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_uuid_t),
+ "::",
+ stringify!(id)
+ )
+ );
+}
+impl _ze_device_property_flags_t {
+ #[doc = "< Device is integrated with the Host."]
+ pub const ZE_DEVICE_PROPERTY_FLAG_INTEGRATED: _ze_device_property_flags_t =
+ _ze_device_property_flags_t(1);
+}
+impl _ze_device_property_flags_t {
+ #[doc = "< Device handle used for query represents a sub-device."]
+ pub const ZE_DEVICE_PROPERTY_FLAG_SUBDEVICE: _ze_device_property_flags_t =
+ _ze_device_property_flags_t(2);
+}
+impl _ze_device_property_flags_t {
+ #[doc = "< Device supports error correction memory access."]
+ pub const ZE_DEVICE_PROPERTY_FLAG_ECC: _ze_device_property_flags_t =
+ _ze_device_property_flags_t(4);
+}
+impl _ze_device_property_flags_t {
+ #[doc = "< Device supports on-demand page-faulting."]
+ pub const ZE_DEVICE_PROPERTY_FLAG_ONDEMANDPAGING: _ze_device_property_flags_t =
+ _ze_device_property_flags_t(8);
+}
+impl _ze_device_property_flags_t {
+ pub const ZE_DEVICE_PROPERTY_FLAG_FORCE_UINT32: _ze_device_property_flags_t =
+ _ze_device_property_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_device_property_flags_t> for _ze_device_property_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_device_property_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_device_property_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_device_property_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_device_property_flags_t> for _ze_device_property_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_device_property_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_device_property_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_device_property_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported device property flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_device_property_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported device property flags"]
+pub use self::_ze_device_property_flags_t as ze_device_property_flags_t;
+#[doc = ""]
+#[doc = " @brief Device properties queried using ::zeDeviceGetProperties"]
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct _ze_device_properties_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in,out][optional] pointer to extension-specific structure"]
+ pub pNext: *mut ::std::os::raw::c_void,
+ #[doc = "< [out] generic device type"]
+ pub type_: ze_device_type_t,
+ #[doc = "< [out] vendor id from PCI configuration"]
+ pub vendorId: u32,
+ #[doc = "< [out] device id from PCI configuration"]
+ pub deviceId: u32,
+ #[doc = "< [out] 0 (none) or a valid combination of ::ze_device_property_flags_t"]
+ pub flags: ze_device_property_flags_t,
+ #[doc = "< [out] sub-device id. Only valid if ::ZE_DEVICE_PROPERTY_FLAG_SUBDEVICE"]
+ #[doc = "< is set."]
+ pub subdeviceId: u32,
+ #[doc = "< [out] Clock rate for device core."]
+ pub coreClockRate: u32,
+ #[doc = "< [out] Maximum memory allocation size."]
+ pub maxMemAllocSize: u64,
+ #[doc = "< [out] Maximum number of logical hardware contexts."]
+ pub maxHardwareContexts: u32,
+ #[doc = "< [out] Maximum priority for command queues. Higher value is higher"]
+ #[doc = "< priority."]
+ pub maxCommandQueuePriority: u32,
+ #[doc = "< [out] Number of threads per EU."]
+ pub numThreadsPerEU: u32,
+ #[doc = "< [out] The physical EU simd width."]
+ pub physicalEUSimdWidth: u32,
+ #[doc = "< [out] Number of EUs per sub-slice."]
+ pub numEUsPerSubslice: u32,
+ #[doc = "< [out] Number of sub-slices per slice."]
+ pub numSubslicesPerSlice: u32,
+ #[doc = "< [out] Number of slices."]
+ pub numSlices: u32,
+ #[doc = "< [out] Returns the resolution of device timer in nanoseconds used for"]
+ #[doc = "< profiling, timestamps, etc."]
+ pub timerResolution: u64,
+ #[doc = "< [out] Returns the number of valid bits in the timestamp value."]
+ pub timestampValidBits: u32,
+ #[doc = "< [out] Returns the number of valid bits in the kernel timestamp values"]
+ pub kernelTimestampValidBits: u32,
+ #[doc = "< [out] universal unique identifier. Note: Subdevices will have their"]
+ #[doc = "< own uuid."]
+ pub uuid: ze_device_uuid_t,
+ #[doc = "< [out] Device name"]
+ pub name: [::std::os::raw::c_char; 256usize],
+}
+#[test]
+fn bindgen_test_layout__ze_device_properties_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_device_properties_t>(),
+ 368usize,
+ concat!("Size of: ", stringify!(_ze_device_properties_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_device_properties_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_device_properties_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_device_properties_t>())).stype as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_device_properties_t>())).pNext as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_device_properties_t>())).type_ as *const _ as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(type_)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_properties_t>())).vendorId as *const _ as usize
+ },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(vendorId)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_properties_t>())).deviceId as *const _ as usize
+ },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(deviceId)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_device_properties_t>())).flags as *const _ as usize },
+ 28usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(flags)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_properties_t>())).subdeviceId as *const _ as usize
+ },
+ 32usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(subdeviceId)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_properties_t>())).coreClockRate as *const _ as usize
+ },
+ 36usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(coreClockRate)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_properties_t>())).maxMemAllocSize as *const _ as usize
+ },
+ 40usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(maxMemAllocSize)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_properties_t>())).maxHardwareContexts as *const _
+ as usize
+ },
+ 48usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(maxHardwareContexts)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_properties_t>())).maxCommandQueuePriority as *const _
+ as usize
+ },
+ 52usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(maxCommandQueuePriority)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_properties_t>())).numThreadsPerEU as *const _ as usize
+ },
+ 56usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(numThreadsPerEU)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_properties_t>())).physicalEUSimdWidth as *const _
+ as usize
+ },
+ 60usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(physicalEUSimdWidth)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_properties_t>())).numEUsPerSubslice as *const _
+ as usize
+ },
+ 64usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(numEUsPerSubslice)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_properties_t>())).numSubslicesPerSlice as *const _
+ as usize
+ },
+ 68usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(numSubslicesPerSlice)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_properties_t>())).numSlices as *const _ as usize
+ },
+ 72usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(numSlices)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_properties_t>())).timerResolution as *const _ as usize
+ },
+ 80usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(timerResolution)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_properties_t>())).timestampValidBits as *const _
+ as usize
+ },
+ 88usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(timestampValidBits)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_properties_t>())).kernelTimestampValidBits as *const _
+ as usize
+ },
+ 92usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(kernelTimestampValidBits)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_device_properties_t>())).uuid as *const _ as usize },
+ 96usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(uuid)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_device_properties_t>())).name as *const _ as usize },
+ 112usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_properties_t),
+ "::",
+ stringify!(name)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves properties of the device."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - clGetDeviceInfo"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pDeviceProperties`"]
+ pub fn zeDeviceGetProperties(
+ hDevice: ze_device_handle_t,
+ pDeviceProperties: *mut ze_device_properties_t,
+ ) -> ze_result_t;
+}
+#[doc = ""]
+#[doc = " @brief Device compute properties queried using ::zeDeviceGetComputeProperties"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_device_compute_properties_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in,out][optional] pointer to extension-specific structure"]
+ pub pNext: *mut ::std::os::raw::c_void,
+ #[doc = "< [out] Maximum items per compute group. (groupSizeX * groupSizeY *"]
+ #[doc = "< groupSizeZ) <= maxTotalGroupSize"]
+ pub maxTotalGroupSize: u32,
+ #[doc = "< [out] Maximum items for X dimension in group"]
+ pub maxGroupSizeX: u32,
+ #[doc = "< [out] Maximum items for Y dimension in group"]
+ pub maxGroupSizeY: u32,
+ #[doc = "< [out] Maximum items for Z dimension in group"]
+ pub maxGroupSizeZ: u32,
+ #[doc = "< [out] Maximum groups that can be launched for x dimension"]
+ pub maxGroupCountX: u32,
+ #[doc = "< [out] Maximum groups that can be launched for y dimension"]
+ pub maxGroupCountY: u32,
+ #[doc = "< [out] Maximum groups that can be launched for z dimension"]
+ pub maxGroupCountZ: u32,
+ #[doc = "< [out] Maximum shared local memory per group."]
+ pub maxSharedLocalMemory: u32,
+ #[doc = "< [out] Number of subgroup sizes supported. This indicates number of"]
+ #[doc = "< entries in subGroupSizes."]
+ pub numSubGroupSizes: u32,
+ #[doc = "< [out] Size group sizes supported."]
+ pub subGroupSizes: [u32; 8usize],
+}
+#[test]
+fn bindgen_test_layout__ze_device_compute_properties_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_device_compute_properties_t>(),
+ 88usize,
+ concat!("Size of: ", stringify!(_ze_device_compute_properties_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_device_compute_properties_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_device_compute_properties_t))
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_compute_properties_t>())).stype as *const _ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_compute_properties_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_compute_properties_t>())).pNext as *const _ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_compute_properties_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_compute_properties_t>())).maxTotalGroupSize
+ as *const _ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_compute_properties_t),
+ "::",
+ stringify!(maxTotalGroupSize)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_compute_properties_t>())).maxGroupSizeX as *const _
+ as usize
+ },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_compute_properties_t),
+ "::",
+ stringify!(maxGroupSizeX)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_compute_properties_t>())).maxGroupSizeY as *const _
+ as usize
+ },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_compute_properties_t),
+ "::",
+ stringify!(maxGroupSizeY)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_compute_properties_t>())).maxGroupSizeZ as *const _
+ as usize
+ },
+ 28usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_compute_properties_t),
+ "::",
+ stringify!(maxGroupSizeZ)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_compute_properties_t>())).maxGroupCountX as *const _
+ as usize
+ },
+ 32usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_compute_properties_t),
+ "::",
+ stringify!(maxGroupCountX)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_compute_properties_t>())).maxGroupCountY as *const _
+ as usize
+ },
+ 36usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_compute_properties_t),
+ "::",
+ stringify!(maxGroupCountY)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_compute_properties_t>())).maxGroupCountZ as *const _
+ as usize
+ },
+ 40usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_compute_properties_t),
+ "::",
+ stringify!(maxGroupCountZ)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_compute_properties_t>())).maxSharedLocalMemory
+ as *const _ as usize
+ },
+ 44usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_compute_properties_t),
+ "::",
+ stringify!(maxSharedLocalMemory)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_compute_properties_t>())).numSubGroupSizes as *const _
+ as usize
+ },
+ 48usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_compute_properties_t),
+ "::",
+ stringify!(numSubGroupSizes)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_compute_properties_t>())).subGroupSizes as *const _
+ as usize
+ },
+ 52usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_compute_properties_t),
+ "::",
+ stringify!(subGroupSizes)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves compute properties of the device."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - clGetDeviceInfo"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pComputeProperties`"]
+ pub fn zeDeviceGetComputeProperties(
+ hDevice: ze_device_handle_t,
+ pComputeProperties: *mut ze_device_compute_properties_t,
+ ) -> ze_result_t;
+}
+#[doc = ""]
+#[doc = " @brief Native kernel universal unique id (UUID)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_native_kernel_uuid_t {
+ #[doc = "< [out] opaque data representing a native kernel UUID"]
+ pub id: [u8; 16usize],
+}
+#[test]
+fn bindgen_test_layout__ze_native_kernel_uuid_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_native_kernel_uuid_t>(),
+ 16usize,
+ concat!("Size of: ", stringify!(_ze_native_kernel_uuid_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_native_kernel_uuid_t>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(_ze_native_kernel_uuid_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_native_kernel_uuid_t>())).id as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_native_kernel_uuid_t),
+ "::",
+ stringify!(id)
+ )
+ );
+}
+impl _ze_device_module_flags_t {
+ #[doc = "< Device supports 16-bit floating-point operations"]
+ pub const ZE_DEVICE_MODULE_FLAG_FP16: _ze_device_module_flags_t = _ze_device_module_flags_t(1);
+}
+impl _ze_device_module_flags_t {
+ #[doc = "< Device supports 64-bit floating-point operations"]
+ pub const ZE_DEVICE_MODULE_FLAG_FP64: _ze_device_module_flags_t = _ze_device_module_flags_t(2);
+}
+impl _ze_device_module_flags_t {
+ #[doc = "< Device supports 64-bit atomic operations"]
+ pub const ZE_DEVICE_MODULE_FLAG_INT64_ATOMICS: _ze_device_module_flags_t =
+ _ze_device_module_flags_t(4);
+}
+impl _ze_device_module_flags_t {
+ #[doc = "< Device supports four component dot product and accumulate operations"]
+ pub const ZE_DEVICE_MODULE_FLAG_DP4A: _ze_device_module_flags_t = _ze_device_module_flags_t(8);
+}
+impl _ze_device_module_flags_t {
+ pub const ZE_DEVICE_MODULE_FLAG_FORCE_UINT32: _ze_device_module_flags_t =
+ _ze_device_module_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_device_module_flags_t> for _ze_device_module_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_device_module_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_device_module_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_device_module_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_device_module_flags_t> for _ze_device_module_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_device_module_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_device_module_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_device_module_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported device module flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_device_module_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported device module flags"]
+pub use self::_ze_device_module_flags_t as ze_device_module_flags_t;
+impl _ze_device_fp_flags_t {
+ #[doc = "< Supports denorms"]
+ pub const ZE_DEVICE_FP_FLAG_DENORM: _ze_device_fp_flags_t = _ze_device_fp_flags_t(1);
+}
+impl _ze_device_fp_flags_t {
+ #[doc = "< Supports INF and quiet NaNs"]
+ pub const ZE_DEVICE_FP_FLAG_INF_NAN: _ze_device_fp_flags_t = _ze_device_fp_flags_t(2);
+}
+impl _ze_device_fp_flags_t {
+ #[doc = "< Supports rounding to nearest even rounding mode"]
+ pub const ZE_DEVICE_FP_FLAG_ROUND_TO_NEAREST: _ze_device_fp_flags_t = _ze_device_fp_flags_t(4);
+}
+impl _ze_device_fp_flags_t {
+ #[doc = "< Supports rounding to zero."]
+ pub const ZE_DEVICE_FP_FLAG_ROUND_TO_ZERO: _ze_device_fp_flags_t = _ze_device_fp_flags_t(8);
+}
+impl _ze_device_fp_flags_t {
+ #[doc = "< Supports rounding to both positive and negative INF."]
+ pub const ZE_DEVICE_FP_FLAG_ROUND_TO_INF: _ze_device_fp_flags_t = _ze_device_fp_flags_t(16);
+}
+impl _ze_device_fp_flags_t {
+ #[doc = "< Supports IEEE754-2008 fused multiply-add."]
+ pub const ZE_DEVICE_FP_FLAG_FMA: _ze_device_fp_flags_t = _ze_device_fp_flags_t(32);
+}
+impl _ze_device_fp_flags_t {
+ #[doc = "< Supports rounding as defined by IEEE754 for divide and sqrt"]
+ #[doc = "< operations."]
+ pub const ZE_DEVICE_FP_FLAG_ROUNDED_DIVIDE_SQRT: _ze_device_fp_flags_t =
+ _ze_device_fp_flags_t(64);
+}
+impl _ze_device_fp_flags_t {
+ #[doc = "< Uses software implementation for basic floating-point operations."]
+ pub const ZE_DEVICE_FP_FLAG_SOFT_FLOAT: _ze_device_fp_flags_t = _ze_device_fp_flags_t(128);
+}
+impl _ze_device_fp_flags_t {
+ pub const ZE_DEVICE_FP_FLAG_FORCE_UINT32: _ze_device_fp_flags_t =
+ _ze_device_fp_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_device_fp_flags_t> for _ze_device_fp_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_device_fp_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_device_fp_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_device_fp_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_device_fp_flags_t> for _ze_device_fp_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_device_fp_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_device_fp_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_device_fp_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported floating-Point capability flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_device_fp_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported floating-Point capability flags"]
+pub use self::_ze_device_fp_flags_t as ze_device_fp_flags_t;
+#[doc = ""]
+#[doc = " @brief Device module properties queried using ::zeDeviceGetModuleProperties"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_device_module_properties_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in,out][optional] pointer to extension-specific structure"]
+ pub pNext: *mut ::std::os::raw::c_void,
+ #[doc = "< [out] Maximum supported SPIR-V version."]
+ #[doc = "< Returns zero if SPIR-V is not supported."]
+ #[doc = "< Contains major and minor attributes, use ::ZE_MAJOR_VERSION and ::ZE_MINOR_VERSION."]
+ pub spirvVersionSupported: u32,
+ #[doc = "< [out] 0 or a valid combination of ::ze_device_module_flags_t"]
+ pub flags: ze_device_module_flags_t,
+ #[doc = "< [out] Capabilities for half-precision floating-point operations."]
+ #[doc = "< returns 0 (if ::ZE_DEVICE_MODULE_FLAG_FP16 is not set) or a"]
+ #[doc = "< combination of ::ze_device_fp_flags_t."]
+ pub fp16flags: ze_device_fp_flags_t,
+ #[doc = "< [out] Capabilities for single-precision floating-point operations."]
+ #[doc = "< returns a combination of ::ze_device_fp_flags_t."]
+ pub fp32flags: ze_device_fp_flags_t,
+ #[doc = "< [out] Capabilities for double-precision floating-point operations."]
+ #[doc = "< returns 0 (if ::ZE_DEVICE_MODULE_FLAG_FP64 is not set) or a"]
+ #[doc = "< combination of ::ze_device_fp_flags_t."]
+ pub fp64flags: ze_device_fp_flags_t,
+ #[doc = "< [out] Maximum kernel argument size that is supported."]
+ pub maxArgumentsSize: u32,
+ #[doc = "< [out] Maximum size of internal buffer that holds output of printf"]
+ #[doc = "< calls from kernel."]
+ pub printfBufferSize: u32,
+ #[doc = "< [out] Compatibility UUID of supported native kernel."]
+ #[doc = "< UUID may or may not be the same across driver release, devices, or"]
+ #[doc = "< operating systems."]
+ #[doc = "< Application is responsible for ensuring UUID matches before creating"]
+ #[doc = "< module using"]
+ #[doc = "< previously created native kernel."]
+ pub nativeKernelSupported: ze_native_kernel_uuid_t,
+}
+#[test]
+fn bindgen_test_layout__ze_device_module_properties_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_device_module_properties_t>(),
+ 64usize,
+ concat!("Size of: ", stringify!(_ze_device_module_properties_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_device_module_properties_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_device_module_properties_t))
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_module_properties_t>())).stype as *const _ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_module_properties_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_module_properties_t>())).pNext as *const _ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_module_properties_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_module_properties_t>())).spirvVersionSupported
+ as *const _ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_module_properties_t),
+ "::",
+ stringify!(spirvVersionSupported)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_module_properties_t>())).flags as *const _ as usize
+ },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_module_properties_t),
+ "::",
+ stringify!(flags)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_module_properties_t>())).fp16flags as *const _
+ as usize
+ },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_module_properties_t),
+ "::",
+ stringify!(fp16flags)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_module_properties_t>())).fp32flags as *const _
+ as usize
+ },
+ 28usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_module_properties_t),
+ "::",
+ stringify!(fp32flags)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_module_properties_t>())).fp64flags as *const _
+ as usize
+ },
+ 32usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_module_properties_t),
+ "::",
+ stringify!(fp64flags)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_module_properties_t>())).maxArgumentsSize as *const _
+ as usize
+ },
+ 36usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_module_properties_t),
+ "::",
+ stringify!(maxArgumentsSize)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_module_properties_t>())).printfBufferSize as *const _
+ as usize
+ },
+ 40usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_module_properties_t),
+ "::",
+ stringify!(printfBufferSize)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_module_properties_t>())).nativeKernelSupported
+ as *const _ as usize
+ },
+ 44usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_module_properties_t),
+ "::",
+ stringify!(nativeKernelSupported)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves module properties of the device"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pModuleProperties`"]
+ pub fn zeDeviceGetModuleProperties(
+ hDevice: ze_device_handle_t,
+ pModuleProperties: *mut ze_device_module_properties_t,
+ ) -> ze_result_t;
+}
+impl _ze_command_queue_group_property_flags_t {
+ #[doc = "< Command queue group supports enqueing compute commands."]
+ pub const ZE_COMMAND_QUEUE_GROUP_PROPERTY_FLAG_COMPUTE:
+ _ze_command_queue_group_property_flags_t = _ze_command_queue_group_property_flags_t(1);
+}
+impl _ze_command_queue_group_property_flags_t {
+ #[doc = "< Command queue group supports enqueing copy commands."]
+ pub const ZE_COMMAND_QUEUE_GROUP_PROPERTY_FLAG_COPY: _ze_command_queue_group_property_flags_t =
+ _ze_command_queue_group_property_flags_t(2);
+}
+impl _ze_command_queue_group_property_flags_t {
+ #[doc = "< Command queue group supports cooperative kernels."]
+ #[doc = "< See ::zeCommandListAppendLaunchCooperativeKernel for more details."]
+ pub const ZE_COMMAND_QUEUE_GROUP_PROPERTY_FLAG_COOPERATIVE_KERNELS:
+ _ze_command_queue_group_property_flags_t = _ze_command_queue_group_property_flags_t(4);
+}
+impl _ze_command_queue_group_property_flags_t {
+ #[doc = "< Command queue groups supports metric streamers and queries."]
+ pub const ZE_COMMAND_QUEUE_GROUP_PROPERTY_FLAG_METRICS:
+ _ze_command_queue_group_property_flags_t = _ze_command_queue_group_property_flags_t(8);
+}
+impl _ze_command_queue_group_property_flags_t {
+ pub const ZE_COMMAND_QUEUE_GROUP_PROPERTY_FLAG_FORCE_UINT32:
+ _ze_command_queue_group_property_flags_t =
+ _ze_command_queue_group_property_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_command_queue_group_property_flags_t>
+ for _ze_command_queue_group_property_flags_t
+{
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_command_queue_group_property_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_command_queue_group_property_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_command_queue_group_property_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_command_queue_group_property_flags_t>
+ for _ze_command_queue_group_property_flags_t
+{
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_command_queue_group_property_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_command_queue_group_property_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_command_queue_group_property_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported command queue group property flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_command_queue_group_property_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported command queue group property flags"]
+pub use self::_ze_command_queue_group_property_flags_t as ze_command_queue_group_property_flags_t;
+#[doc = ""]
+#[doc = " @brief Command queue group properties queried using"]
+#[doc = " ::zeDeviceGetCommandQueueGroupProperties"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_command_queue_group_properties_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in,out][optional] pointer to extension-specific structure"]
+ pub pNext: *mut ::std::os::raw::c_void,
+ #[doc = "< [out] 0 (none) or a valid combination of"]
+ #[doc = "< ::ze_command_queue_group_property_flags_t"]
+ pub flags: ze_command_queue_group_property_flags_t,
+ #[doc = "< [out] maximum `pattern_size` supported by command queue group."]
+ #[doc = "< See ::zeCommandListAppendMemoryFill for more details."]
+ pub maxMemoryFillPatternSize: usize,
+ #[doc = "< [out] the number of physical command queues within the group."]
+ pub numQueues: u32,
+}
+#[test]
+fn bindgen_test_layout__ze_command_queue_group_properties_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_command_queue_group_properties_t>(),
+ 40usize,
+ concat!(
+ "Size of: ",
+ stringify!(_ze_command_queue_group_properties_t)
+ )
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_command_queue_group_properties_t>(),
+ 8usize,
+ concat!(
+ "Alignment of ",
+ stringify!(_ze_command_queue_group_properties_t)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_command_queue_group_properties_t>())).stype as *const _
+ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_command_queue_group_properties_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_command_queue_group_properties_t>())).pNext as *const _
+ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_command_queue_group_properties_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_command_queue_group_properties_t>())).flags as *const _
+ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_command_queue_group_properties_t),
+ "::",
+ stringify!(flags)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_command_queue_group_properties_t>()))
+ .maxMemoryFillPatternSize as *const _ as usize
+ },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_command_queue_group_properties_t),
+ "::",
+ stringify!(maxMemoryFillPatternSize)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_command_queue_group_properties_t>())).numQueues as *const _
+ as usize
+ },
+ 32usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_command_queue_group_properties_t),
+ "::",
+ stringify!(numQueues)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves command queue group properties of the device."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Properties are reported for each physical command queue type supported"]
+ #[doc = " by the device."]
+ #[doc = " - Multiple calls to this function will return properties in the same"]
+ #[doc = " order."]
+ #[doc = " - The order in which the properties are returned defines the command"]
+ #[doc = " queue group's ordinal."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - **vkGetPhysicalDeviceQueueFamilyProperties**"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pCount`"]
+ pub fn zeDeviceGetCommandQueueGroupProperties(
+ hDevice: ze_device_handle_t,
+ pCount: *mut u32,
+ pCommandQueueGroupProperties: *mut ze_command_queue_group_properties_t,
+ ) -> ze_result_t;
+}
+impl _ze_device_memory_property_flags_t {
+ #[doc = "< reserved for future use"]
+ pub const ZE_DEVICE_MEMORY_PROPERTY_FLAG_TBD: _ze_device_memory_property_flags_t =
+ _ze_device_memory_property_flags_t(1);
+}
+impl _ze_device_memory_property_flags_t {
+ pub const ZE_DEVICE_MEMORY_PROPERTY_FLAG_FORCE_UINT32: _ze_device_memory_property_flags_t =
+ _ze_device_memory_property_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_device_memory_property_flags_t> for _ze_device_memory_property_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_device_memory_property_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_device_memory_property_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_device_memory_property_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_device_memory_property_flags_t> for _ze_device_memory_property_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_device_memory_property_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_device_memory_property_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_device_memory_property_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported device memory property flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_device_memory_property_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported device memory property flags"]
+pub use self::_ze_device_memory_property_flags_t as ze_device_memory_property_flags_t;
+#[doc = ""]
+#[doc = " @brief Device local memory properties queried using"]
+#[doc = " ::zeDeviceGetMemoryProperties"]
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct _ze_device_memory_properties_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in,out][optional] pointer to extension-specific structure"]
+ pub pNext: *mut ::std::os::raw::c_void,
+ #[doc = "< [out] 0 (none) or a valid combination of"]
+ #[doc = "< ::ze_device_memory_property_flags_t"]
+ pub flags: ze_device_memory_property_flags_t,
+ #[doc = "< [out] Maximum clock rate for device memory."]
+ pub maxClockRate: u32,
+ #[doc = "< [out] Maximum bus width between device and memory."]
+ pub maxBusWidth: u32,
+ #[doc = "< [out] Total memory size in bytes that is available to the device."]
+ pub totalSize: u64,
+ #[doc = "< [out] Memory name"]
+ pub name: [::std::os::raw::c_char; 256usize],
+}
+#[test]
+fn bindgen_test_layout__ze_device_memory_properties_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_device_memory_properties_t>(),
+ 296usize,
+ concat!("Size of: ", stringify!(_ze_device_memory_properties_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_device_memory_properties_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_device_memory_properties_t))
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_memory_properties_t>())).stype as *const _ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_memory_properties_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_memory_properties_t>())).pNext as *const _ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_memory_properties_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_memory_properties_t>())).flags as *const _ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_memory_properties_t),
+ "::",
+ stringify!(flags)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_memory_properties_t>())).maxClockRate as *const _
+ as usize
+ },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_memory_properties_t),
+ "::",
+ stringify!(maxClockRate)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_memory_properties_t>())).maxBusWidth as *const _
+ as usize
+ },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_memory_properties_t),
+ "::",
+ stringify!(maxBusWidth)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_memory_properties_t>())).totalSize as *const _
+ as usize
+ },
+ 32usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_memory_properties_t),
+ "::",
+ stringify!(totalSize)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_memory_properties_t>())).name as *const _ as usize
+ },
+ 40usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_memory_properties_t),
+ "::",
+ stringify!(name)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves local memory properties of the device."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Properties are reported for each physical memory type supported by the"]
+ #[doc = " device."]
+ #[doc = " - Multiple calls to this function will return properties in the same"]
+ #[doc = " order."]
+ #[doc = " - The order in which the properties are returned defines the device's"]
+ #[doc = " local memory ordinal."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - clGetDeviceInfo"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pCount`"]
+ pub fn zeDeviceGetMemoryProperties(
+ hDevice: ze_device_handle_t,
+ pCount: *mut u32,
+ pMemProperties: *mut ze_device_memory_properties_t,
+ ) -> ze_result_t;
+}
+impl _ze_memory_access_cap_flags_t {
+ #[doc = "< Supports load/store access"]
+ pub const ZE_MEMORY_ACCESS_CAP_FLAG_RW: _ze_memory_access_cap_flags_t =
+ _ze_memory_access_cap_flags_t(1);
+}
+impl _ze_memory_access_cap_flags_t {
+ #[doc = "< Supports atomic access"]
+ pub const ZE_MEMORY_ACCESS_CAP_FLAG_ATOMIC: _ze_memory_access_cap_flags_t =
+ _ze_memory_access_cap_flags_t(2);
+}
+impl _ze_memory_access_cap_flags_t {
+ #[doc = "< Supports concurrent access"]
+ pub const ZE_MEMORY_ACCESS_CAP_FLAG_CONCURRENT: _ze_memory_access_cap_flags_t =
+ _ze_memory_access_cap_flags_t(4);
+}
+impl _ze_memory_access_cap_flags_t {
+ #[doc = "< Supports concurrent atomic access"]
+ pub const ZE_MEMORY_ACCESS_CAP_FLAG_CONCURRENT_ATOMIC: _ze_memory_access_cap_flags_t =
+ _ze_memory_access_cap_flags_t(8);
+}
+impl _ze_memory_access_cap_flags_t {
+ pub const ZE_MEMORY_ACCESS_CAP_FLAG_FORCE_UINT32: _ze_memory_access_cap_flags_t =
+ _ze_memory_access_cap_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_memory_access_cap_flags_t> for _ze_memory_access_cap_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_memory_access_cap_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_memory_access_cap_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_memory_access_cap_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_memory_access_cap_flags_t> for _ze_memory_access_cap_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_memory_access_cap_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_memory_access_cap_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_memory_access_cap_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Memory access capability flags"]
+#[doc = ""]
+#[doc = " @details"]
+#[doc = " - Supported access capabilities for different types of memory"]
+#[doc = " allocations"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_memory_access_cap_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Memory access capability flags"]
+#[doc = ""]
+#[doc = " @details"]
+#[doc = " - Supported access capabilities for different types of memory"]
+#[doc = " allocations"]
+pub use self::_ze_memory_access_cap_flags_t as ze_memory_access_cap_flags_t;
+#[doc = ""]
+#[doc = " @brief Device memory access properties queried using"]
+#[doc = " ::zeDeviceGetMemoryAccessProperties"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_device_memory_access_properties_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in,out][optional] pointer to extension-specific structure"]
+ pub pNext: *mut ::std::os::raw::c_void,
+ #[doc = "< [out] host memory capabilities."]
+ #[doc = "< returns 0 (unsupported) or a combination of ::ze_memory_access_cap_flags_t."]
+ pub hostAllocCapabilities: ze_memory_access_cap_flags_t,
+ #[doc = "< [out] device memory capabilities."]
+ #[doc = "< returns 0 (unsupported) or a combination of ::ze_memory_access_cap_flags_t."]
+ pub deviceAllocCapabilities: ze_memory_access_cap_flags_t,
+ #[doc = "< [out] shared, single-device memory capabilities."]
+ #[doc = "< returns 0 (unsupported) or a combination of ::ze_memory_access_cap_flags_t."]
+ pub sharedSingleDeviceAllocCapabilities: ze_memory_access_cap_flags_t,
+ #[doc = "< [out] shared, cross-device memory capabilities."]
+ #[doc = "< returns 0 (unsupported) or a combination of ::ze_memory_access_cap_flags_t."]
+ pub sharedCrossDeviceAllocCapabilities: ze_memory_access_cap_flags_t,
+ #[doc = "< [out] shared, system memory capabilities."]
+ #[doc = "< returns 0 (unsupported) or a combination of ::ze_memory_access_cap_flags_t."]
+ pub sharedSystemAllocCapabilities: ze_memory_access_cap_flags_t,
+}
+#[test]
+fn bindgen_test_layout__ze_device_memory_access_properties_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_device_memory_access_properties_t>(),
+ 40usize,
+ concat!(
+ "Size of: ",
+ stringify!(_ze_device_memory_access_properties_t)
+ )
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_device_memory_access_properties_t>(),
+ 8usize,
+ concat!(
+ "Alignment of ",
+ stringify!(_ze_device_memory_access_properties_t)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_memory_access_properties_t>())).stype as *const _
+ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_memory_access_properties_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_memory_access_properties_t>())).pNext as *const _
+ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_memory_access_properties_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_memory_access_properties_t>())).hostAllocCapabilities
+ as *const _ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_memory_access_properties_t),
+ "::",
+ stringify!(hostAllocCapabilities)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_memory_access_properties_t>()))
+ .deviceAllocCapabilities as *const _ as usize
+ },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_memory_access_properties_t),
+ "::",
+ stringify!(deviceAllocCapabilities)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_memory_access_properties_t>()))
+ .sharedSingleDeviceAllocCapabilities as *const _ as usize
+ },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_memory_access_properties_t),
+ "::",
+ stringify!(sharedSingleDeviceAllocCapabilities)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_memory_access_properties_t>()))
+ .sharedCrossDeviceAllocCapabilities as *const _ as usize
+ },
+ 28usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_memory_access_properties_t),
+ "::",
+ stringify!(sharedCrossDeviceAllocCapabilities)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_memory_access_properties_t>()))
+ .sharedSystemAllocCapabilities as *const _ as usize
+ },
+ 32usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_memory_access_properties_t),
+ "::",
+ stringify!(sharedSystemAllocCapabilities)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves memory access properties of the device."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - clGetDeviceInfo"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pMemAccessProperties`"]
+ pub fn zeDeviceGetMemoryAccessProperties(
+ hDevice: ze_device_handle_t,
+ pMemAccessProperties: *mut ze_device_memory_access_properties_t,
+ ) -> ze_result_t;
+}
+impl _ze_device_cache_property_flags_t {
+ #[doc = "< Device support User Cache Control (i.e. SLM section vs Generic Cache)"]
+ pub const ZE_DEVICE_CACHE_PROPERTY_FLAG_USER_CONTROL: _ze_device_cache_property_flags_t =
+ _ze_device_cache_property_flags_t(1);
+}
+impl _ze_device_cache_property_flags_t {
+ pub const ZE_DEVICE_CACHE_PROPERTY_FLAG_FORCE_UINT32: _ze_device_cache_property_flags_t =
+ _ze_device_cache_property_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_device_cache_property_flags_t> for _ze_device_cache_property_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_device_cache_property_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_device_cache_property_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_device_cache_property_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_device_cache_property_flags_t> for _ze_device_cache_property_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_device_cache_property_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_device_cache_property_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_device_cache_property_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported cache control property flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_device_cache_property_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported cache control property flags"]
+pub use self::_ze_device_cache_property_flags_t as ze_device_cache_property_flags_t;
+#[doc = ""]
+#[doc = " @brief Device cache properties queried using ::zeDeviceGetCacheProperties"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_device_cache_properties_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in,out][optional] pointer to extension-specific structure"]
+ pub pNext: *mut ::std::os::raw::c_void,
+ #[doc = "< [out] 0 (none) or a valid combination of"]
+ #[doc = "< ::ze_device_cache_property_flags_t"]
+ pub flags: ze_device_cache_property_flags_t,
+ #[doc = "< [out] Per-cache size, in bytes"]
+ pub cacheSize: usize,
+}
+#[test]
+fn bindgen_test_layout__ze_device_cache_properties_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_device_cache_properties_t>(),
+ 32usize,
+ concat!("Size of: ", stringify!(_ze_device_cache_properties_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_device_cache_properties_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_device_cache_properties_t))
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_cache_properties_t>())).stype as *const _ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_cache_properties_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_cache_properties_t>())).pNext as *const _ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_cache_properties_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_cache_properties_t>())).flags as *const _ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_cache_properties_t),
+ "::",
+ stringify!(flags)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_cache_properties_t>())).cacheSize as *const _ as usize
+ },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_cache_properties_t),
+ "::",
+ stringify!(cacheSize)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves cache properties of the device"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - clGetDeviceInfo"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pCount`"]
+ pub fn zeDeviceGetCacheProperties(
+ hDevice: ze_device_handle_t,
+ pCount: *mut u32,
+ pCacheProperties: *mut ze_device_cache_properties_t,
+ ) -> ze_result_t;
+}
+#[doc = ""]
+#[doc = " @brief Device image properties queried using ::zeDeviceGetImageProperties"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_device_image_properties_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in,out][optional] pointer to extension-specific structure"]
+ pub pNext: *mut ::std::os::raw::c_void,
+ #[doc = "< [out] Maximum image dimensions for 1D resources. if 0, then 1D images"]
+ #[doc = "< are unsupported."]
+ pub maxImageDims1D: u32,
+ #[doc = "< [out] Maximum image dimensions for 2D resources. if 0, then 2D images"]
+ #[doc = "< are unsupported."]
+ pub maxImageDims2D: u32,
+ #[doc = "< [out] Maximum image dimensions for 3D resources. if 0, then 3D images"]
+ #[doc = "< are unsupported."]
+ pub maxImageDims3D: u32,
+ #[doc = "< [out] Maximum image buffer size in bytes. if 0, then buffer images are"]
+ #[doc = "< unsupported."]
+ pub maxImageBufferSize: u64,
+ #[doc = "< [out] Maximum image array slices. if 0, then image arrays are"]
+ #[doc = "< unsupported."]
+ pub maxImageArraySlices: u32,
+ #[doc = "< [out] Max samplers that can be used in kernel. if 0, then sampling is"]
+ #[doc = "< unsupported."]
+ pub maxSamplers: u32,
+ #[doc = "< [out] Returns the maximum number of simultaneous image objects that"]
+ #[doc = "< can be read from by a kernel. if 0, then reading images is"]
+ #[doc = "< unsupported."]
+ pub maxReadImageArgs: u32,
+ #[doc = "< [out] Returns the maximum number of simultaneous image objects that"]
+ #[doc = "< can be written to by a kernel. if 0, then writing images is"]
+ #[doc = "< unsupported."]
+ pub maxWriteImageArgs: u32,
+}
+#[test]
+fn bindgen_test_layout__ze_device_image_properties_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_device_image_properties_t>(),
+ 56usize,
+ concat!("Size of: ", stringify!(_ze_device_image_properties_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_device_image_properties_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_device_image_properties_t))
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_image_properties_t>())).stype as *const _ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_image_properties_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_image_properties_t>())).pNext as *const _ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_image_properties_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_image_properties_t>())).maxImageDims1D as *const _
+ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_image_properties_t),
+ "::",
+ stringify!(maxImageDims1D)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_image_properties_t>())).maxImageDims2D as *const _
+ as usize
+ },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_image_properties_t),
+ "::",
+ stringify!(maxImageDims2D)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_image_properties_t>())).maxImageDims3D as *const _
+ as usize
+ },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_image_properties_t),
+ "::",
+ stringify!(maxImageDims3D)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_image_properties_t>())).maxImageBufferSize as *const _
+ as usize
+ },
+ 32usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_image_properties_t),
+ "::",
+ stringify!(maxImageBufferSize)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_image_properties_t>())).maxImageArraySlices
+ as *const _ as usize
+ },
+ 40usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_image_properties_t),
+ "::",
+ stringify!(maxImageArraySlices)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_image_properties_t>())).maxSamplers as *const _
+ as usize
+ },
+ 44usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_image_properties_t),
+ "::",
+ stringify!(maxSamplers)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_image_properties_t>())).maxReadImageArgs as *const _
+ as usize
+ },
+ 48usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_image_properties_t),
+ "::",
+ stringify!(maxReadImageArgs)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_image_properties_t>())).maxWriteImageArgs as *const _
+ as usize
+ },
+ 52usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_image_properties_t),
+ "::",
+ stringify!(maxWriteImageArgs)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves image properties of the device"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - See ::zeImageGetProperties for format-specific capabilities."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pImageProperties`"]
+ pub fn zeDeviceGetImageProperties(
+ hDevice: ze_device_handle_t,
+ pImageProperties: *mut ze_device_image_properties_t,
+ ) -> ze_result_t;
+}
+#[doc = ""]
+#[doc = " @brief Device external memory import and export properties"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_device_external_memory_properties_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in,out][optional] pointer to extension-specific structure"]
+ pub pNext: *mut ::std::os::raw::c_void,
+ #[doc = "< [out] Supported external memory import types for memory allocations."]
+ pub memoryAllocationImportTypes: ze_external_memory_type_flags_t,
+ #[doc = "< [out] Supported external memory export types for memory allocations."]
+ pub memoryAllocationExportTypes: ze_external_memory_type_flags_t,
+ #[doc = "< [out] Supported external memory import types for images."]
+ pub imageImportTypes: ze_external_memory_type_flags_t,
+ #[doc = "< [out] Supported external memory export types for images."]
+ pub imageExportTypes: ze_external_memory_type_flags_t,
+}
+#[test]
+fn bindgen_test_layout__ze_device_external_memory_properties_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_device_external_memory_properties_t>(),
+ 32usize,
+ concat!(
+ "Size of: ",
+ stringify!(_ze_device_external_memory_properties_t)
+ )
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_device_external_memory_properties_t>(),
+ 8usize,
+ concat!(
+ "Alignment of ",
+ stringify!(_ze_device_external_memory_properties_t)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_external_memory_properties_t>())).stype as *const _
+ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_external_memory_properties_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_external_memory_properties_t>())).pNext as *const _
+ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_external_memory_properties_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_external_memory_properties_t>()))
+ .memoryAllocationImportTypes as *const _ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_external_memory_properties_t),
+ "::",
+ stringify!(memoryAllocationImportTypes)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_external_memory_properties_t>()))
+ .memoryAllocationExportTypes as *const _ as usize
+ },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_external_memory_properties_t),
+ "::",
+ stringify!(memoryAllocationExportTypes)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_external_memory_properties_t>())).imageImportTypes
+ as *const _ as usize
+ },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_external_memory_properties_t),
+ "::",
+ stringify!(imageImportTypes)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_external_memory_properties_t>())).imageExportTypes
+ as *const _ as usize
+ },
+ 28usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_external_memory_properties_t),
+ "::",
+ stringify!(imageExportTypes)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves external memory import and export of the device"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pExternalMemoryProperties`"]
+ pub fn zeDeviceGetExternalMemoryProperties(
+ hDevice: ze_device_handle_t,
+ pExternalMemoryProperties: *mut ze_device_external_memory_properties_t,
+ ) -> ze_result_t;
+}
+impl _ze_device_p2p_property_flags_t {
+ #[doc = "< Device supports access between peer devices."]
+ pub const ZE_DEVICE_P2P_PROPERTY_FLAG_ACCESS: _ze_device_p2p_property_flags_t =
+ _ze_device_p2p_property_flags_t(1);
+}
+impl _ze_device_p2p_property_flags_t {
+ #[doc = "< Device supports atomics between peer devices."]
+ pub const ZE_DEVICE_P2P_PROPERTY_FLAG_ATOMICS: _ze_device_p2p_property_flags_t =
+ _ze_device_p2p_property_flags_t(2);
+}
+impl _ze_device_p2p_property_flags_t {
+ pub const ZE_DEVICE_P2P_PROPERTY_FLAG_FORCE_UINT32: _ze_device_p2p_property_flags_t =
+ _ze_device_p2p_property_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_device_p2p_property_flags_t> for _ze_device_p2p_property_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_device_p2p_property_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_device_p2p_property_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_device_p2p_property_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_device_p2p_property_flags_t> for _ze_device_p2p_property_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_device_p2p_property_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_device_p2p_property_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_device_p2p_property_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported device peer-to-peer property flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_device_p2p_property_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported device peer-to-peer property flags"]
+pub use self::_ze_device_p2p_property_flags_t as ze_device_p2p_property_flags_t;
+#[doc = ""]
+#[doc = " @brief Device peer-to-peer properties queried using"]
+#[doc = " ::zeDeviceGetP2PProperties"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_device_p2p_properties_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in,out][optional] pointer to extension-specific structure"]
+ pub pNext: *mut ::std::os::raw::c_void,
+ #[doc = "< [out] 0 (none) or a valid combination of"]
+ #[doc = "< ::ze_device_p2p_property_flags_t"]
+ pub flags: ze_device_p2p_property_flags_t,
+}
+#[test]
+fn bindgen_test_layout__ze_device_p2p_properties_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_device_p2p_properties_t>(),
+ 24usize,
+ concat!("Size of: ", stringify!(_ze_device_p2p_properties_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_device_p2p_properties_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_device_p2p_properties_t))
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_p2p_properties_t>())).stype as *const _ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_p2p_properties_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_p2p_properties_t>())).pNext as *const _ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_p2p_properties_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_p2p_properties_t>())).flags as *const _ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_p2p_properties_t),
+ "::",
+ stringify!(flags)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves peer-to-peer properties between one device and a peer"]
+ #[doc = " devices"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " + `nullptr == hPeerDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pP2PProperties`"]
+ pub fn zeDeviceGetP2PProperties(
+ hDevice: ze_device_handle_t,
+ hPeerDevice: ze_device_handle_t,
+ pP2PProperties: *mut ze_device_p2p_properties_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Queries if one device can directly access peer device allocations"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Any device can access any other device within a node through a"]
+ #[doc = " scale-up fabric."]
+ #[doc = " - The following are conditions for CanAccessPeer query."]
+ #[doc = " + If both device and peer device are the same then return true."]
+ #[doc = " + If both sub-device and peer sub-device are the same then return"]
+ #[doc = " true."]
+ #[doc = " + If both are sub-devices and share the same parent device then"]
+ #[doc = " return true."]
+ #[doc = " + If both device and remote device are connected by a direct or"]
+ #[doc = " indirect scale-up fabric or over PCIe (same root complex or shared"]
+ #[doc = " PCIe switch) then true."]
+ #[doc = " + If both sub-device and remote parent device (and vice-versa) are"]
+ #[doc = " connected by a direct or indirect scale-up fabric or over PCIe"]
+ #[doc = " (same root complex or shared PCIe switch) then true."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " + `nullptr == hPeerDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == value`"]
+ pub fn zeDeviceCanAccessPeer(
+ hDevice: ze_device_handle_t,
+ hPeerDevice: ze_device_handle_t,
+ value: *mut ze_bool_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Returns current status of the device."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Once a device is reset, this call will update the OS handle attached"]
+ #[doc = " to the device handle."]
+ #[doc = " - The application may call this function from simultaneous threads with"]
+ #[doc = " the same device handle."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " + Device is available for use."]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " + Device is lost; must be reset for use."]
+ pub fn zeDeviceGetStatus(hDevice: ze_device_handle_t) -> ze_result_t;
+}
+impl _ze_context_flags_t {
+ #[doc = "< reserved for future use"]
+ pub const ZE_CONTEXT_FLAG_TBD: _ze_context_flags_t = _ze_context_flags_t(1);
+}
+impl _ze_context_flags_t {
+ pub const ZE_CONTEXT_FLAG_FORCE_UINT32: _ze_context_flags_t = _ze_context_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_context_flags_t> for _ze_context_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_context_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_context_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_context_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_context_flags_t> for _ze_context_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_context_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_context_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_context_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported context creation flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_context_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported context creation flags"]
+pub use self::_ze_context_flags_t as ze_context_flags_t;
+#[doc = ""]
+#[doc = " @brief Context descriptor"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_context_desc_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in][optional] pointer to extension-specific structure"]
+ pub pNext: *const ::std::os::raw::c_void,
+ #[doc = "< [in] creation flags."]
+ #[doc = "< must be 0 (default) or a valid combination of ::ze_context_flags_t;"]
+ #[doc = "< default behavior may use implicit driver-based heuristics."]
+ pub flags: ze_context_flags_t,
+}
+#[test]
+fn bindgen_test_layout__ze_context_desc_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_context_desc_t>(),
+ 24usize,
+ concat!("Size of: ", stringify!(_ze_context_desc_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_context_desc_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_context_desc_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_context_desc_t>())).stype as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_context_desc_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_context_desc_t>())).pNext as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_context_desc_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_context_desc_t>())).flags as *const _ as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_context_desc_t),
+ "::",
+ stringify!(flags)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Creates a context for the driver."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must only use the context for the driver which was"]
+ #[doc = " provided during creation."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDriver`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == desc`"]
+ #[doc = " + `nullptr == phContext`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `0x1 < desc->flags`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ pub fn zeContextCreate(
+ hDriver: ze_driver_handle_t,
+ desc: *const ze_context_desc_t,
+ phContext: *mut ze_context_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Destroys a context."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the device is not currently referencing"]
+ #[doc = " the context before it is deleted."]
+ #[doc = " - The implementation of this function may immediately free all Host and"]
+ #[doc = " Device allocations associated with this context."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same context handle."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE"]
+ pub fn zeContextDestroy(hContext: ze_context_handle_t) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Returns current status of the context."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads with"]
+ #[doc = " the same context handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " + Context is available for use."]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " + Context is invalid; due to device lost or reset."]
+ pub fn zeContextGetStatus(hContext: ze_context_handle_t) -> ze_result_t;
+}
+impl _ze_command_queue_flags_t {
+ #[doc = "< command queue should be optimized for submission to a single device engine."]
+ #[doc = "< driver **must** disable any implicit optimizations for distributing"]
+ #[doc = "< work across multiple engines."]
+ #[doc = "< this flag should be used when applications want full control over"]
+ #[doc = "< multi-engine submission and scheduling."]
+ pub const ZE_COMMAND_QUEUE_FLAG_EXPLICIT_ONLY: _ze_command_queue_flags_t =
+ _ze_command_queue_flags_t(1);
+}
+impl _ze_command_queue_flags_t {
+ pub const ZE_COMMAND_QUEUE_FLAG_FORCE_UINT32: _ze_command_queue_flags_t =
+ _ze_command_queue_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_command_queue_flags_t> for _ze_command_queue_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_command_queue_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_command_queue_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_command_queue_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_command_queue_flags_t> for _ze_command_queue_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_command_queue_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_command_queue_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_command_queue_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported command queue flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_command_queue_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported command queue flags"]
+pub use self::_ze_command_queue_flags_t as ze_command_queue_flags_t;
+impl _ze_command_queue_mode_t {
+ #[doc = "< implicit default behavior; uses driver-based heuristics"]
+ pub const ZE_COMMAND_QUEUE_MODE_DEFAULT: _ze_command_queue_mode_t = _ze_command_queue_mode_t(0);
+}
+impl _ze_command_queue_mode_t {
+ #[doc = "< Device execution always completes immediately on execute;"]
+ #[doc = "< Host thread is blocked using wait on implicit synchronization object"]
+ pub const ZE_COMMAND_QUEUE_MODE_SYNCHRONOUS: _ze_command_queue_mode_t =
+ _ze_command_queue_mode_t(1);
+}
+impl _ze_command_queue_mode_t {
+ #[doc = "< Device execution is scheduled and will complete in future;"]
+ #[doc = "< explicit synchronization object must be used to determine completeness"]
+ pub const ZE_COMMAND_QUEUE_MODE_ASYNCHRONOUS: _ze_command_queue_mode_t =
+ _ze_command_queue_mode_t(2);
+}
+impl _ze_command_queue_mode_t {
+ pub const ZE_COMMAND_QUEUE_MODE_FORCE_UINT32: _ze_command_queue_mode_t =
+ _ze_command_queue_mode_t(2147483647);
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported command queue modes"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_command_queue_mode_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported command queue modes"]
+pub use self::_ze_command_queue_mode_t as ze_command_queue_mode_t;
+impl _ze_command_queue_priority_t {
+ #[doc = "< [default] normal priority"]
+ pub const ZE_COMMAND_QUEUE_PRIORITY_NORMAL: _ze_command_queue_priority_t =
+ _ze_command_queue_priority_t(0);
+}
+impl _ze_command_queue_priority_t {
+ #[doc = "< lower priority than normal"]
+ pub const ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW: _ze_command_queue_priority_t =
+ _ze_command_queue_priority_t(1);
+}
+impl _ze_command_queue_priority_t {
+ #[doc = "< higher priority than normal"]
+ pub const ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_HIGH: _ze_command_queue_priority_t =
+ _ze_command_queue_priority_t(2);
+}
+impl _ze_command_queue_priority_t {
+ pub const ZE_COMMAND_QUEUE_PRIORITY_FORCE_UINT32: _ze_command_queue_priority_t =
+ _ze_command_queue_priority_t(2147483647);
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported command queue priorities"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_command_queue_priority_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported command queue priorities"]
+pub use self::_ze_command_queue_priority_t as ze_command_queue_priority_t;
+#[doc = ""]
+#[doc = " @brief Command Queue descriptor"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_command_queue_desc_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in][optional] pointer to extension-specific structure"]
+ pub pNext: *const ::std::os::raw::c_void,
+ #[doc = "< [in] command queue group ordinal"]
+ pub ordinal: u32,
+ #[doc = "< [in] command queue index within the group;"]
+ #[doc = "< must be zero if ::ZE_COMMAND_QUEUE_FLAG_EXPLICIT_ONLY is not set"]
+ pub index: u32,
+ #[doc = "< [in] usage flags."]
+ #[doc = "< must be 0 (default) or a valid combination of ::ze_command_queue_flags_t;"]
+ #[doc = "< default behavior may use implicit driver-based heuristics to balance"]
+ #[doc = "< latency and throughput."]
+ pub flags: ze_command_queue_flags_t,
+ #[doc = "< [in] operation mode"]
+ pub mode: ze_command_queue_mode_t,
+ #[doc = "< [in] priority"]
+ pub priority: ze_command_queue_priority_t,
+}
+#[test]
+fn bindgen_test_layout__ze_command_queue_desc_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_command_queue_desc_t>(),
+ 40usize,
+ concat!("Size of: ", stringify!(_ze_command_queue_desc_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_command_queue_desc_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_command_queue_desc_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_command_queue_desc_t>())).stype as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_command_queue_desc_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_command_queue_desc_t>())).pNext as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_command_queue_desc_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_command_queue_desc_t>())).ordinal as *const _ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_command_queue_desc_t),
+ "::",
+ stringify!(ordinal)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_command_queue_desc_t>())).index as *const _ as usize },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_command_queue_desc_t),
+ "::",
+ stringify!(index)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_command_queue_desc_t>())).flags as *const _ as usize },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_command_queue_desc_t),
+ "::",
+ stringify!(flags)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_command_queue_desc_t>())).mode as *const _ as usize },
+ 28usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_command_queue_desc_t),
+ "::",
+ stringify!(mode)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_command_queue_desc_t>())).priority as *const _ as usize
+ },
+ 32usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_command_queue_desc_t),
+ "::",
+ stringify!(priority)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Creates a command queue on the context."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - A command queue represents a logical input stream to the device, tied"]
+ #[doc = " to a physical input stream."]
+ #[doc = " - The application must only use the command queue for the device, or its"]
+ #[doc = " sub-devices, which was provided during creation."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - **clCreateCommandQueue**"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == desc`"]
+ #[doc = " + `nullptr == phCommandQueue`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `0x1 < desc->flags`"]
+ #[doc = " + `::ZE_COMMAND_QUEUE_MODE_ASYNCHRONOUS < desc->mode`"]
+ #[doc = " + `::ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_HIGH < desc->priority`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ pub fn zeCommandQueueCreate(
+ hContext: ze_context_handle_t,
+ hDevice: ze_device_handle_t,
+ desc: *const ze_command_queue_desc_t,
+ phCommandQueue: *mut ze_command_queue_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Destroys a command queue."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must destroy all fence handles created from the"]
+ #[doc = " command queue before destroying the command queue itself"]
+ #[doc = " - The application must ensure the device is not currently referencing"]
+ #[doc = " the command queue before it is deleted"]
+ #[doc = " - The implementation of this function may immediately free all Host and"]
+ #[doc = " Device allocations associated with this command queue"]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command queue handle."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - **clReleaseCommandQueue**"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandQueue`"]
+ #[doc = " - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE"]
+ pub fn zeCommandQueueDestroy(hCommandQueue: ze_command_queue_handle_t) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Executes a command list in a command queue."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the command lists are accessible by the"]
+ #[doc = " device on which the command queue was created."]
+ #[doc = " - The application must only execute command lists created with an"]
+ #[doc = " identical command queue group ordinal to the command queue."]
+ #[doc = " - The application must use a fence created using the same command queue."]
+ #[doc = " - The application must ensure the command queue, command list and fence"]
+ #[doc = " were created on the same context."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - vkQueueSubmit"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandQueue`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == phCommandLists`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `0 == numCommandLists`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_COMMAND_LIST_TYPE"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ pub fn zeCommandQueueExecuteCommandLists(
+ hCommandQueue: ze_command_queue_handle_t,
+ numCommandLists: u32,
+ phCommandLists: *mut ze_command_list_handle_t,
+ hFence: ze_fence_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Synchronizes a command queue by waiting on the host."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandQueue`"]
+ #[doc = " - ::ZE_RESULT_NOT_READY"]
+ #[doc = " + timeout expired"]
+ pub fn zeCommandQueueSynchronize(
+ hCommandQueue: ze_command_queue_handle_t,
+ timeout: u64,
+ ) -> ze_result_t;
+}
+impl _ze_command_list_flags_t {
+ #[doc = "< driver may reorder commands (e.g., kernels, copies) between barriers"]
+ #[doc = "< and synchronization primitives."]
+ #[doc = "< using this flag may increase Host overhead of ::zeCommandListClose."]
+ #[doc = "< therefore, this flag should **not** be set for low-latency usage-models."]
+ pub const ZE_COMMAND_LIST_FLAG_RELAXED_ORDERING: _ze_command_list_flags_t =
+ _ze_command_list_flags_t(1);
+}
+impl _ze_command_list_flags_t {
+ #[doc = "< driver may perform additional optimizations that increase execution"]
+ #[doc = "< throughput."]
+ #[doc = "< using this flag may increase Host overhead of ::zeCommandListClose and ::zeCommandQueueExecuteCommandLists."]
+ #[doc = "< therefore, this flag should **not** be set for low-latency usage-models."]
+ pub const ZE_COMMAND_LIST_FLAG_MAXIMIZE_THROUGHPUT: _ze_command_list_flags_t =
+ _ze_command_list_flags_t(2);
+}
+impl _ze_command_list_flags_t {
+ #[doc = "< command list should be optimized for submission to a single command"]
+ #[doc = "< queue and device engine."]
+ #[doc = "< driver **must** disable any implicit optimizations for distributing"]
+ #[doc = "< work across multiple engines."]
+ #[doc = "< this flag should be used when applications want full control over"]
+ #[doc = "< multi-engine submission and scheduling."]
+ pub const ZE_COMMAND_LIST_FLAG_EXPLICIT_ONLY: _ze_command_list_flags_t =
+ _ze_command_list_flags_t(4);
+}
+impl _ze_command_list_flags_t {
+ pub const ZE_COMMAND_LIST_FLAG_FORCE_UINT32: _ze_command_list_flags_t =
+ _ze_command_list_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_command_list_flags_t> for _ze_command_list_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_command_list_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_command_list_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_command_list_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_command_list_flags_t> for _ze_command_list_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_command_list_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_command_list_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_command_list_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported command list creation flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_command_list_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported command list creation flags"]
+pub use self::_ze_command_list_flags_t as ze_command_list_flags_t;
+#[doc = ""]
+#[doc = " @brief Command List descriptor"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_command_list_desc_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in][optional] pointer to extension-specific structure"]
+ pub pNext: *const ::std::os::raw::c_void,
+ #[doc = "< [in] command queue group ordinal to which this command list will be"]
+ #[doc = "< submitted"]
+ pub commandQueueGroupOrdinal: u32,
+ #[doc = "< [in] usage flags."]
+ #[doc = "< must be 0 (default) or a valid combination of ::ze_command_list_flags_t;"]
+ #[doc = "< default behavior may use implicit driver-based heuristics to balance"]
+ #[doc = "< latency and throughput."]
+ pub flags: ze_command_list_flags_t,
+}
+#[test]
+fn bindgen_test_layout__ze_command_list_desc_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_command_list_desc_t>(),
+ 24usize,
+ concat!("Size of: ", stringify!(_ze_command_list_desc_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_command_list_desc_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_command_list_desc_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_command_list_desc_t>())).stype as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_command_list_desc_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_command_list_desc_t>())).pNext as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_command_list_desc_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_command_list_desc_t>())).commandQueueGroupOrdinal as *const _
+ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_command_list_desc_t),
+ "::",
+ stringify!(commandQueueGroupOrdinal)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_command_list_desc_t>())).flags as *const _ as usize },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_command_list_desc_t),
+ "::",
+ stringify!(flags)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Creates a command list on the context."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - A command list represents a sequence of commands for execution on a"]
+ #[doc = " command queue."]
+ #[doc = " - The command list is created in the 'open' state."]
+ #[doc = " - The application must only use the command list for the device, or its"]
+ #[doc = " sub-devices, which was provided during creation."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == desc`"]
+ #[doc = " + `nullptr == phCommandList`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `0x7 < desc->flags`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ pub fn zeCommandListCreate(
+ hContext: ze_context_handle_t,
+ hDevice: ze_device_handle_t,
+ desc: *const ze_command_list_desc_t,
+ phCommandList: *mut ze_command_list_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Creates an immediate command list on the context."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - An immediate command list is used for low-latency submission of"]
+ #[doc = " commands."]
+ #[doc = " - An immediate command list creates an implicit command queue."]
+ #[doc = " - The command list is created in the 'open' state and never needs to be"]
+ #[doc = " closed."]
+ #[doc = " - The application must only use the command list for the device, or its"]
+ #[doc = " sub-devices, which was provided during creation."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == altdesc`"]
+ #[doc = " + `nullptr == phCommandList`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `0x1 < altdesc->flags`"]
+ #[doc = " + `::ZE_COMMAND_QUEUE_MODE_ASYNCHRONOUS < altdesc->mode`"]
+ #[doc = " + `::ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_HIGH < altdesc->priority`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ pub fn zeCommandListCreateImmediate(
+ hContext: ze_context_handle_t,
+ hDevice: ze_device_handle_t,
+ altdesc: *const ze_command_queue_desc_t,
+ phCommandList: *mut ze_command_list_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Destroys a command list."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the device is not currently referencing"]
+ #[doc = " the command list before it is deleted."]
+ #[doc = " - The implementation of this function may immediately free all Host and"]
+ #[doc = " Device allocations associated with this command list."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE"]
+ pub fn zeCommandListDestroy(hCommandList: ze_command_list_handle_t) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Closes a command list; ready to be executed by a command queue."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ pub fn zeCommandListClose(hCommandList: ze_command_list_handle_t) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Reset a command list to initial (empty) state; ready for appending"]
+ #[doc = " commands."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the device is not currently referencing"]
+ #[doc = " the command list before it is reset"]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ pub fn zeCommandListReset(hCommandList: ze_command_list_handle_t) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Appends a memory write of the device's global timestamp value into a"]
+ #[doc = " command list."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the events are accessible by the device on"]
+ #[doc = " which the command list was created."]
+ #[doc = " - The timestamp frequency can be queried from"]
+ #[doc = " ::ze_device_properties_t.timerResolution."]
+ #[doc = " - The number of valid bits in the timestamp value can be queried from"]
+ #[doc = " ::ze_device_properties_t.timestampValidBits."]
+ #[doc = " - The application must ensure the memory pointed to by dstptr is"]
+ #[doc = " accessible by the device on which the command list was created."]
+ #[doc = " - The application must ensure the command list and events were created,"]
+ #[doc = " and the memory was allocated, on the same context."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == dstptr`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `(nullptr == phWaitEvents) && (0 < numWaitEvents)`"]
+ pub fn zeCommandListAppendWriteGlobalTimestamp(
+ hCommandList: ze_command_list_handle_t,
+ dstptr: *mut u64,
+ hSignalEvent: ze_event_handle_t,
+ numWaitEvents: u32,
+ phWaitEvents: *mut ze_event_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Appends an execution and global memory barrier into a command list."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the events are accessible by the device on"]
+ #[doc = " which the command list was created."]
+ #[doc = " - If numWaitEvents is zero, then all previous commands are completed"]
+ #[doc = " prior to the execution of the barrier."]
+ #[doc = " - If numWaitEvents is non-zero, then then all phWaitEvents must be"]
+ #[doc = " signaled prior to the execution of the barrier."]
+ #[doc = " - This command blocks all following commands from beginning until the"]
+ #[doc = " execution of the barrier completes."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - **vkCmdPipelineBarrier**"]
+ #[doc = " - clEnqueueBarrierWithWaitList"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `(nullptr == phWaitEvents) && (0 < numWaitEvents)`"]
+ pub fn zeCommandListAppendBarrier(
+ hCommandList: ze_command_list_handle_t,
+ hSignalEvent: ze_event_handle_t,
+ numWaitEvents: u32,
+ phWaitEvents: *mut ze_event_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Appends a global memory ranges barrier into a command list."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the events are accessible by the device on"]
+ #[doc = " which the command list was created."]
+ #[doc = " - If numWaitEvents is zero, then all previous commands are completed"]
+ #[doc = " prior to the execution of the barrier."]
+ #[doc = " - If numWaitEvents is non-zero, then then all phWaitEvents must be"]
+ #[doc = " signaled prior to the execution of the barrier."]
+ #[doc = " - This command blocks all following commands from beginning until the"]
+ #[doc = " execution of the barrier completes."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pRangeSizes`"]
+ #[doc = " + `nullptr == pRanges`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `(nullptr == phWaitEvents) && (0 < numWaitEvents)`"]
+ pub fn zeCommandListAppendMemoryRangesBarrier(
+ hCommandList: ze_command_list_handle_t,
+ numRanges: u32,
+ pRangeSizes: *const usize,
+ pRanges: *mut *const ::std::os::raw::c_void,
+ hSignalEvent: ze_event_handle_t,
+ numWaitEvents: u32,
+ phWaitEvents: *mut ze_event_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Ensures in-bound writes to the device are globally observable."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - This is a special-case system level barrier that can be used to ensure"]
+ #[doc = " global observability of writes;"]
+ #[doc = " typically needed after a producer (e.g., NIC) performs direct writes"]
+ #[doc = " to the device's memory (e.g., Direct RDMA writes)."]
+ #[doc = " This is typically required when the memory corresponding to the writes"]
+ #[doc = " is subsequently accessed from a remote device."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " + `nullptr == hDevice`"]
+ pub fn zeContextSystemBarrier(
+ hContext: ze_context_handle_t,
+ hDevice: ze_device_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Copies host, device, or shared memory."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the memory pointed to by dstptr and srcptr"]
+ #[doc = " is accessible by the device on which the command list was created."]
+ #[doc = " - The implementation must not access the memory pointed to by dstptr and"]
+ #[doc = " srcptr as they are free to be modified by either the Host or device up"]
+ #[doc = " until execution."]
+ #[doc = " - The application must ensure the events are accessible by the device on"]
+ #[doc = " which the command list was created."]
+ #[doc = " - The application must ensure the command list and events were created,"]
+ #[doc = " and the memory was allocated, on the same context."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - **clEnqueueCopyBuffer**"]
+ #[doc = " - **clEnqueueReadBuffer**"]
+ #[doc = " - **clEnqueueWriteBuffer**"]
+ #[doc = " - **clEnqueueSVMMemcpy**"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == dstptr`"]
+ #[doc = " + `nullptr == srcptr`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `(nullptr == phWaitEvents) && (0 < numWaitEvents)`"]
+ pub fn zeCommandListAppendMemoryCopy(
+ hCommandList: ze_command_list_handle_t,
+ dstptr: *mut ::std::os::raw::c_void,
+ srcptr: *const ::std::os::raw::c_void,
+ size: usize,
+ hSignalEvent: ze_event_handle_t,
+ numWaitEvents: u32,
+ phWaitEvents: *mut ze_event_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Initializes host, device, or shared memory."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the memory pointed to by dstptr is"]
+ #[doc = " accessible by the device on which the command list was created."]
+ #[doc = " - The implementation must not access the memory pointed to by dstptr as"]
+ #[doc = " it is free to be modified by either the Host or device up until"]
+ #[doc = " execution."]
+ #[doc = " - The value to initialize memory to is described by the pattern and the"]
+ #[doc = " pattern size."]
+ #[doc = " - The pattern size must be a power-of-two and less than"]
+ #[doc = " ::ze_command_queue_group_properties_t.maxMemoryFillPatternSize."]
+ #[doc = " - The application must ensure the events are accessible by the device on"]
+ #[doc = " which the command list was created."]
+ #[doc = " - The application must enusre the command list and events were created,"]
+ #[doc = " and the memory was allocated, on the same context."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - **clEnqueueFillBuffer**"]
+ #[doc = " - **clEnqueueSVMMemFill**"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == ptr`"]
+ #[doc = " + `nullptr == pattern`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `(nullptr == phWaitEvents) && (0 < numWaitEvents)`"]
+ pub fn zeCommandListAppendMemoryFill(
+ hCommandList: ze_command_list_handle_t,
+ ptr: *mut ::std::os::raw::c_void,
+ pattern: *const ::std::os::raw::c_void,
+ pattern_size: usize,
+ size: usize,
+ hSignalEvent: ze_event_handle_t,
+ numWaitEvents: u32,
+ phWaitEvents: *mut ze_event_handle_t,
+ ) -> ze_result_t;
+}
+#[doc = ""]
+#[doc = " @brief Copy region descriptor"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_copy_region_t {
+ #[doc = "< [in] The origin x offset for region in bytes"]
+ pub originX: u32,
+ #[doc = "< [in] The origin y offset for region in rows"]
+ pub originY: u32,
+ #[doc = "< [in] The origin z offset for region in slices"]
+ pub originZ: u32,
+ #[doc = "< [in] The region width relative to origin in bytes"]
+ pub width: u32,
+ #[doc = "< [in] The region height relative to origin in rows"]
+ pub height: u32,
+ #[doc = "< [in] The region depth relative to origin in slices. Set this to 0 for"]
+ #[doc = "< 2D copy."]
+ pub depth: u32,
+}
+#[test]
+fn bindgen_test_layout__ze_copy_region_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_copy_region_t>(),
+ 24usize,
+ concat!("Size of: ", stringify!(_ze_copy_region_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_copy_region_t>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(_ze_copy_region_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_copy_region_t>())).originX as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_copy_region_t),
+ "::",
+ stringify!(originX)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_copy_region_t>())).originY as *const _ as usize },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_copy_region_t),
+ "::",
+ stringify!(originY)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_copy_region_t>())).originZ as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_copy_region_t),
+ "::",
+ stringify!(originZ)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_copy_region_t>())).width as *const _ as usize },
+ 12usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_copy_region_t),
+ "::",
+ stringify!(width)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_copy_region_t>())).height as *const _ as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_copy_region_t),
+ "::",
+ stringify!(height)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_copy_region_t>())).depth as *const _ as usize },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_copy_region_t),
+ "::",
+ stringify!(depth)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Copies a region from a 2D or 3D array of host, device, or shared"]
+ #[doc = " memory."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the memory pointed to by dstptr and srcptr"]
+ #[doc = " is accessible by the device on which the command list was created."]
+ #[doc = " - The implementation must not access the memory pointed to by dstptr and"]
+ #[doc = " srcptr as they are free to be modified by either the Host or device up"]
+ #[doc = " until execution."]
+ #[doc = " - The region width, height, and depth for both src and dst must be same."]
+ #[doc = " The origins can be different."]
+ #[doc = " - The src and dst regions cannot be overlapping."]
+ #[doc = " - The application must ensure the events are accessible by the device on"]
+ #[doc = " which the command list was created."]
+ #[doc = " - The application must ensure the command list and events were created,"]
+ #[doc = " and the memory was allocated, on the same context."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == dstptr`"]
+ #[doc = " + `nullptr == dstRegion`"]
+ #[doc = " + `nullptr == srcptr`"]
+ #[doc = " + `nullptr == srcRegion`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OVERLAPPING_REGIONS"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `(nullptr == phWaitEvents) && (0 < numWaitEvents)`"]
+ pub fn zeCommandListAppendMemoryCopyRegion(
+ hCommandList: ze_command_list_handle_t,
+ dstptr: *mut ::std::os::raw::c_void,
+ dstRegion: *const ze_copy_region_t,
+ dstPitch: u32,
+ dstSlicePitch: u32,
+ srcptr: *const ::std::os::raw::c_void,
+ srcRegion: *const ze_copy_region_t,
+ srcPitch: u32,
+ srcSlicePitch: u32,
+ hSignalEvent: ze_event_handle_t,
+ numWaitEvents: u32,
+ phWaitEvents: *mut ze_event_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Copies host, device, or shared memory from another context."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The current active and source context must be from the same driver."]
+ #[doc = " - The application must ensure the memory pointed to by dstptr and srcptr"]
+ #[doc = " is accessible by the device on which the command list was created."]
+ #[doc = " - The implementation must not access the memory pointed to by dstptr and"]
+ #[doc = " srcptr as they are free to be modified by either the Host or device up"]
+ #[doc = " until execution."]
+ #[doc = " - The application must ensure the events are accessible by the device on"]
+ #[doc = " which the command list was created."]
+ #[doc = " - The application must ensure the command list and events were created,"]
+ #[doc = " and the memory was allocated, on the same context."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " + `nullptr == hContextSrc`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == dstptr`"]
+ #[doc = " + `nullptr == srcptr`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `(nullptr == phWaitEvents) && (0 < numWaitEvents)`"]
+ pub fn zeCommandListAppendMemoryCopyFromContext(
+ hCommandList: ze_command_list_handle_t,
+ dstptr: *mut ::std::os::raw::c_void,
+ hContextSrc: ze_context_handle_t,
+ srcptr: *const ::std::os::raw::c_void,
+ size: usize,
+ hSignalEvent: ze_event_handle_t,
+ numWaitEvents: u32,
+ phWaitEvents: *mut ze_event_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Copies an image."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the image and events are accessible by the"]
+ #[doc = " device on which the command list was created."]
+ #[doc = " - The application must ensure the image format descriptors for both"]
+ #[doc = " source and destination images are the same."]
+ #[doc = " - The application must ensure the command list, images and events were"]
+ #[doc = " created on the same context."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - **clEnqueueCopyImage**"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " + `nullptr == hDstImage`"]
+ #[doc = " + `nullptr == hSrcImage`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `(nullptr == phWaitEvents) && (0 < numWaitEvents)`"]
+ pub fn zeCommandListAppendImageCopy(
+ hCommandList: ze_command_list_handle_t,
+ hDstImage: ze_image_handle_t,
+ hSrcImage: ze_image_handle_t,
+ hSignalEvent: ze_event_handle_t,
+ numWaitEvents: u32,
+ phWaitEvents: *mut ze_event_handle_t,
+ ) -> ze_result_t;
+}
+#[doc = ""]
+#[doc = " @brief Region descriptor"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_image_region_t {
+ #[doc = "< [in] The origin x offset for region in pixels"]
+ pub originX: u32,
+ #[doc = "< [in] The origin y offset for region in pixels"]
+ pub originY: u32,
+ #[doc = "< [in] The origin z offset for region in pixels"]
+ pub originZ: u32,
+ #[doc = "< [in] The region width relative to origin in pixels"]
+ pub width: u32,
+ #[doc = "< [in] The region height relative to origin in pixels"]
+ pub height: u32,
+ #[doc = "< [in] The region depth relative to origin. For 1D or 2D images, set"]
+ #[doc = "< this to 1."]
+ pub depth: u32,
+}
+#[test]
+fn bindgen_test_layout__ze_image_region_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_image_region_t>(),
+ 24usize,
+ concat!("Size of: ", stringify!(_ze_image_region_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_image_region_t>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(_ze_image_region_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_region_t>())).originX as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_region_t),
+ "::",
+ stringify!(originX)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_region_t>())).originY as *const _ as usize },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_region_t),
+ "::",
+ stringify!(originY)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_region_t>())).originZ as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_region_t),
+ "::",
+ stringify!(originZ)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_region_t>())).width as *const _ as usize },
+ 12usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_region_t),
+ "::",
+ stringify!(width)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_region_t>())).height as *const _ as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_region_t),
+ "::",
+ stringify!(height)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_region_t>())).depth as *const _ as usize },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_region_t),
+ "::",
+ stringify!(depth)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Copies a region of an image to another image."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the image and events are accessible by the"]
+ #[doc = " device on which the command list was created."]
+ #[doc = " - The region width and height for both src and dst must be same. The"]
+ #[doc = " origins can be different."]
+ #[doc = " - The src and dst regions cannot be overlapping."]
+ #[doc = " - The application must ensure the image format descriptors for both"]
+ #[doc = " source and destination images are the same."]
+ #[doc = " - The application must ensure the command list, images and events were"]
+ #[doc = " created, and the memory was allocated, on the same context."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " + `nullptr == hDstImage`"]
+ #[doc = " + `nullptr == hSrcImage`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_ERROR_OVERLAPPING_REGIONS"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `(nullptr == phWaitEvents) && (0 < numWaitEvents)`"]
+ pub fn zeCommandListAppendImageCopyRegion(
+ hCommandList: ze_command_list_handle_t,
+ hDstImage: ze_image_handle_t,
+ hSrcImage: ze_image_handle_t,
+ pDstRegion: *const ze_image_region_t,
+ pSrcRegion: *const ze_image_region_t,
+ hSignalEvent: ze_event_handle_t,
+ numWaitEvents: u32,
+ phWaitEvents: *mut ze_event_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Copies from an image to device or shared memory."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the memory pointed to by dstptr is"]
+ #[doc = " accessible by the device on which the command list was created."]
+ #[doc = " - The implementation must not access the memory pointed to by dstptr as"]
+ #[doc = " it is free to be modified by either the Host or device up until"]
+ #[doc = " execution."]
+ #[doc = " - The application must ensure the image and events are accessible by the"]
+ #[doc = " device on which the command list was created."]
+ #[doc = " - The application must ensure the image format descriptor for the source"]
+ #[doc = " image is not a media format."]
+ #[doc = " - The application must ensure the command list, image and events were"]
+ #[doc = " created, and the memory was allocated, on the same context."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - clEnqueueReadImage"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " + `nullptr == hSrcImage`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == dstptr`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `(nullptr == phWaitEvents) && (0 < numWaitEvents)`"]
+ pub fn zeCommandListAppendImageCopyToMemory(
+ hCommandList: ze_command_list_handle_t,
+ dstptr: *mut ::std::os::raw::c_void,
+ hSrcImage: ze_image_handle_t,
+ pSrcRegion: *const ze_image_region_t,
+ hSignalEvent: ze_event_handle_t,
+ numWaitEvents: u32,
+ phWaitEvents: *mut ze_event_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Copies to an image from device or shared memory."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the memory pointed to by srcptr is"]
+ #[doc = " accessible by the device on which the command list was created."]
+ #[doc = " - The implementation must not access the memory pointed to by srcptr as"]
+ #[doc = " it is free to be modified by either the Host or device up until"]
+ #[doc = " execution."]
+ #[doc = " - The application must ensure the image and events are accessible by the"]
+ #[doc = " device on which the command list was created."]
+ #[doc = " - The application must ensure the image format descriptor for the"]
+ #[doc = " destination image is not a media format."]
+ #[doc = " - The application must ensure the command list, image and events were"]
+ #[doc = " created, and the memory was allocated, on the same context."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - clEnqueueWriteImage"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " + `nullptr == hDstImage`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == srcptr`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `(nullptr == phWaitEvents) && (0 < numWaitEvents)`"]
+ pub fn zeCommandListAppendImageCopyFromMemory(
+ hCommandList: ze_command_list_handle_t,
+ hDstImage: ze_image_handle_t,
+ srcptr: *const ::std::os::raw::c_void,
+ pDstRegion: *const ze_image_region_t,
+ hSignalEvent: ze_event_handle_t,
+ numWaitEvents: u32,
+ phWaitEvents: *mut ze_event_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Asynchronously prefetches shared memory to the device associated with"]
+ #[doc = " the specified command list"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - This is a hint to improve performance only and is not required for"]
+ #[doc = " correctness."]
+ #[doc = " - Only prefetching to the device associated with the specified command"]
+ #[doc = " list is supported."]
+ #[doc = " Prefetching to the host or to a peer device is not supported."]
+ #[doc = " - Prefetching may not be supported for all allocation types for all devices."]
+ #[doc = " If memory prefetching is not supported for the specified memory range"]
+ #[doc = " the prefetch hint may be ignored."]
+ #[doc = " - Prefetching may only be supported at a device-specific granularity,"]
+ #[doc = " such as at a page boundary."]
+ #[doc = " In this case, the memory range may be expanded such that the start and"]
+ #[doc = " end of the range satisfy granularity requirements."]
+ #[doc = " - The application must ensure the memory pointed to by ptr is accessible"]
+ #[doc = " by the device on which the command list was created."]
+ #[doc = " - The application must ensure the command list was created, and the"]
+ #[doc = " memory was allocated, on the same context."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - clEnqueueSVMMigrateMem"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == ptr`"]
+ pub fn zeCommandListAppendMemoryPrefetch(
+ hCommandList: ze_command_list_handle_t,
+ ptr: *const ::std::os::raw::c_void,
+ size: usize,
+ ) -> ze_result_t;
+}
+impl _ze_memory_advice_t {
+ #[doc = "< hint that memory will be read from frequently and written to rarely"]
+ pub const ZE_MEMORY_ADVICE_SET_READ_MOSTLY: _ze_memory_advice_t = _ze_memory_advice_t(0);
+}
+impl _ze_memory_advice_t {
+ #[doc = "< removes the affect of ::ZE_MEMORY_ADVICE_SET_READ_MOSTLY"]
+ pub const ZE_MEMORY_ADVICE_CLEAR_READ_MOSTLY: _ze_memory_advice_t = _ze_memory_advice_t(1);
+}
+impl _ze_memory_advice_t {
+ #[doc = "< hint that the preferred memory location is the specified device"]
+ pub const ZE_MEMORY_ADVICE_SET_PREFERRED_LOCATION: _ze_memory_advice_t = _ze_memory_advice_t(2);
+}
+impl _ze_memory_advice_t {
+ #[doc = "< removes the affect of ::ZE_MEMORY_ADVICE_SET_PREFERRED_LOCATION"]
+ pub const ZE_MEMORY_ADVICE_CLEAR_PREFERRED_LOCATION: _ze_memory_advice_t =
+ _ze_memory_advice_t(3);
+}
+impl _ze_memory_advice_t {
+ #[doc = "< hints that memory will mostly be accessed non-atomically"]
+ pub const ZE_MEMORY_ADVICE_SET_NON_ATOMIC_MOSTLY: _ze_memory_advice_t = _ze_memory_advice_t(4);
+}
+impl _ze_memory_advice_t {
+ #[doc = "< removes the affect of ::ZE_MEMORY_ADVICE_SET_NON_ATOMIC_MOSTLY"]
+ pub const ZE_MEMORY_ADVICE_CLEAR_NON_ATOMIC_MOSTLY: _ze_memory_advice_t =
+ _ze_memory_advice_t(5);
+}
+impl _ze_memory_advice_t {
+ #[doc = "< hints that memory should be cached"]
+ pub const ZE_MEMORY_ADVICE_BIAS_CACHED: _ze_memory_advice_t = _ze_memory_advice_t(6);
+}
+impl _ze_memory_advice_t {
+ #[doc = "< hints that memory should be not be cached"]
+ pub const ZE_MEMORY_ADVICE_BIAS_UNCACHED: _ze_memory_advice_t = _ze_memory_advice_t(7);
+}
+impl _ze_memory_advice_t {
+ pub const ZE_MEMORY_ADVICE_FORCE_UINT32: _ze_memory_advice_t = _ze_memory_advice_t(2147483647);
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported memory advice hints"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_memory_advice_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported memory advice hints"]
+pub use self::_ze_memory_advice_t as ze_memory_advice_t;
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Provides advice about the use of a shared memory range"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Memory advice is a performance hint only and is not required for"]
+ #[doc = " functional correctness."]
+ #[doc = " - Memory advice can be used to override driver heuristics to explicitly"]
+ #[doc = " control shared memory behavior."]
+ #[doc = " - Not all memory advice hints may be supported for all allocation types"]
+ #[doc = " for all devices."]
+ #[doc = " If a memory advice hint is not supported by the device it will be ignored."]
+ #[doc = " - Memory advice may only be supported at a device-specific granularity,"]
+ #[doc = " such as at a page boundary."]
+ #[doc = " In this case, the memory range may be expanded such that the start and"]
+ #[doc = " end of the range satisfy granularity requirements."]
+ #[doc = " - The application must ensure the memory pointed to by ptr is accessible"]
+ #[doc = " by the device on which the command list was created."]
+ #[doc = " - The application must ensure the command list was created, and memory"]
+ #[doc = " was allocated, on the same context."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle, and the memory was"]
+ #[doc = " allocated."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == ptr`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `::ZE_MEMORY_ADVICE_BIAS_UNCACHED < advice`"]
+ pub fn zeCommandListAppendMemAdvise(
+ hCommandList: ze_command_list_handle_t,
+ hDevice: ze_device_handle_t,
+ ptr: *const ::std::os::raw::c_void,
+ size: usize,
+ advice: ze_memory_advice_t,
+ ) -> ze_result_t;
+}
+impl _ze_event_pool_flags_t {
+ #[doc = "< signals and waits are also visible to host"]
+ pub const ZE_EVENT_POOL_FLAG_HOST_VISIBLE: _ze_event_pool_flags_t = _ze_event_pool_flags_t(1);
+}
+impl _ze_event_pool_flags_t {
+ #[doc = "< signals and waits may be shared across processes"]
+ pub const ZE_EVENT_POOL_FLAG_IPC: _ze_event_pool_flags_t = _ze_event_pool_flags_t(2);
+}
+impl _ze_event_pool_flags_t {
+ #[doc = "< Indicates all events in pool will contain kernel timestamps; cannot be"]
+ #[doc = "< combined with ::ZE_EVENT_POOL_FLAG_IPC"]
+ pub const ZE_EVENT_POOL_FLAG_KERNEL_TIMESTAMP: _ze_event_pool_flags_t =
+ _ze_event_pool_flags_t(4);
+}
+impl _ze_event_pool_flags_t {
+ pub const ZE_EVENT_POOL_FLAG_FORCE_UINT32: _ze_event_pool_flags_t =
+ _ze_event_pool_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_event_pool_flags_t> for _ze_event_pool_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_event_pool_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_event_pool_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_event_pool_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_event_pool_flags_t> for _ze_event_pool_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_event_pool_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_event_pool_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_event_pool_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported event pool creation flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_event_pool_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported event pool creation flags"]
+pub use self::_ze_event_pool_flags_t as ze_event_pool_flags_t;
+#[doc = ""]
+#[doc = " @brief Event pool descriptor"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_event_pool_desc_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in][optional] pointer to extension-specific structure"]
+ pub pNext: *const ::std::os::raw::c_void,
+ #[doc = "< [in] creation flags."]
+ #[doc = "< must be 0 (default) or a valid combination of ::ze_event_pool_flags_t;"]
+ #[doc = "< default behavior is signals and waits are visible to the entire device"]
+ #[doc = "< and peer devices."]
+ pub flags: ze_event_pool_flags_t,
+ #[doc = "< [in] number of events within the pool; must be greater than 0"]
+ pub count: u32,
+}
+#[test]
+fn bindgen_test_layout__ze_event_pool_desc_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_event_pool_desc_t>(),
+ 24usize,
+ concat!("Size of: ", stringify!(_ze_event_pool_desc_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_event_pool_desc_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_event_pool_desc_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_event_pool_desc_t>())).stype as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_event_pool_desc_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_event_pool_desc_t>())).pNext as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_event_pool_desc_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_event_pool_desc_t>())).flags as *const _ as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_event_pool_desc_t),
+ "::",
+ stringify!(flags)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_event_pool_desc_t>())).count as *const _ as usize },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_event_pool_desc_t),
+ "::",
+ stringify!(count)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Creates a pool of events on the context."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must only use events within the pool for the"]
+ #[doc = " device(s), or their sub-devices, which were provided during creation."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == desc`"]
+ #[doc = " + `nullptr == phEventPool`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `0x7 < desc->flags`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `0 < desc->count`"]
+ #[doc = " + `(nullptr == phDevices) && (0 < numDevices)`"]
+ pub fn zeEventPoolCreate(
+ hContext: ze_context_handle_t,
+ desc: *const ze_event_pool_desc_t,
+ numDevices: u32,
+ phDevices: *mut ze_device_handle_t,
+ phEventPool: *mut ze_event_pool_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Deletes an event pool object."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must destroy all event handles created from the pool"]
+ #[doc = " before destroying the pool itself."]
+ #[doc = " - The application must ensure the device is not currently referencing"]
+ #[doc = " the any event within the pool before it is deleted."]
+ #[doc = " - The implementation of this function may immediately free all Host and"]
+ #[doc = " Device allocations associated with this event pool."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same event pool handle."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hEventPool`"]
+ #[doc = " - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE"]
+ pub fn zeEventPoolDestroy(hEventPool: ze_event_pool_handle_t) -> ze_result_t;
+}
+impl _ze_event_scope_flags_t {
+ #[doc = "< cache hierarchies are flushed or invalidated sufficient for local"]
+ #[doc = "< sub-device access"]
+ pub const ZE_EVENT_SCOPE_FLAG_SUBDEVICE: _ze_event_scope_flags_t = _ze_event_scope_flags_t(1);
+}
+impl _ze_event_scope_flags_t {
+ #[doc = "< cache hierarchies are flushed or invalidated sufficient for global"]
+ #[doc = "< device access and peer device access"]
+ pub const ZE_EVENT_SCOPE_FLAG_DEVICE: _ze_event_scope_flags_t = _ze_event_scope_flags_t(2);
+}
+impl _ze_event_scope_flags_t {
+ #[doc = "< cache hierarchies are flushed or invalidated sufficient for device and"]
+ #[doc = "< host access"]
+ pub const ZE_EVENT_SCOPE_FLAG_HOST: _ze_event_scope_flags_t = _ze_event_scope_flags_t(4);
+}
+impl _ze_event_scope_flags_t {
+ pub const ZE_EVENT_SCOPE_FLAG_FORCE_UINT32: _ze_event_scope_flags_t =
+ _ze_event_scope_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_event_scope_flags_t> for _ze_event_scope_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_event_scope_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_event_scope_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_event_scope_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_event_scope_flags_t> for _ze_event_scope_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_event_scope_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_event_scope_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_event_scope_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported event scope flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_event_scope_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported event scope flags"]
+pub use self::_ze_event_scope_flags_t as ze_event_scope_flags_t;
+#[doc = ""]
+#[doc = " @brief Event descriptor"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_event_desc_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in][optional] pointer to extension-specific structure"]
+ pub pNext: *const ::std::os::raw::c_void,
+ #[doc = "< [in] index of the event within the pool; must be less-than the count"]
+ #[doc = "< specified during pool creation"]
+ pub index: u32,
+ #[doc = "< [in] defines the scope of relevant cache hierarchies to flush on a"]
+ #[doc = "< signal action before the event is triggered."]
+ #[doc = "< must be 0 (default) or a valid combination of ::ze_event_scope_flags_t;"]
+ #[doc = "< default behavior is execution synchronization only, no cache"]
+ #[doc = "< hierarchies are flushed."]
+ pub signal: ze_event_scope_flags_t,
+ #[doc = "< [in] defines the scope of relevant cache hierarchies to invalidate on"]
+ #[doc = "< a wait action after the event is complete."]
+ #[doc = "< must be 0 (default) or a valid combination of ::ze_event_scope_flags_t;"]
+ #[doc = "< default behavior is execution synchronization only, no cache"]
+ #[doc = "< hierarchies are invalidated."]
+ pub wait: ze_event_scope_flags_t,
+}
+#[test]
+fn bindgen_test_layout__ze_event_desc_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_event_desc_t>(),
+ 32usize,
+ concat!("Size of: ", stringify!(_ze_event_desc_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_event_desc_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_event_desc_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_event_desc_t>())).stype as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_event_desc_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_event_desc_t>())).pNext as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_event_desc_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_event_desc_t>())).index as *const _ as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_event_desc_t),
+ "::",
+ stringify!(index)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_event_desc_t>())).signal as *const _ as usize },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_event_desc_t),
+ "::",
+ stringify!(signal)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_event_desc_t>())).wait as *const _ as usize },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_event_desc_t),
+ "::",
+ stringify!(wait)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Creates an event from the pool."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - An event is used to communicate fine-grain host-to-device,"]
+ #[doc = " device-to-host or device-to-device dependencies have completed."]
+ #[doc = " - The application must ensure the location in the pool is not being used"]
+ #[doc = " by another event."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same event pool handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - **clCreateUserEvent**"]
+ #[doc = " - vkCreateEvent"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hEventPool`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == desc`"]
+ #[doc = " + `nullptr == phEvent`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `0x7 < desc->signal`"]
+ #[doc = " + `0x7 < desc->wait`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ pub fn zeEventCreate(
+ hEventPool: ze_event_pool_handle_t,
+ desc: *const ze_event_desc_t,
+ phEvent: *mut ze_event_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Deletes an event object."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the device is not currently referencing"]
+ #[doc = " the event before it is deleted."]
+ #[doc = " - The implementation of this function may immediately free all Host and"]
+ #[doc = " Device allocations associated with this event."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same event handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - **clReleaseEvent**"]
+ #[doc = " - vkDestroyEvent"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hEvent`"]
+ #[doc = " - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE"]
+ pub fn zeEventDestroy(hEvent: ze_event_handle_t) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Gets an IPC event pool handle for the specified event handle that can"]
+ #[doc = " be shared with another process."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Event pool must have been created with ::ZE_EVENT_POOL_FLAG_IPC."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hEventPool`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == phIpc`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ pub fn zeEventPoolGetIpcHandle(
+ hEventPool: ze_event_pool_handle_t,
+ phIpc: *mut ze_ipc_event_pool_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Opens an IPC event pool handle to retrieve an event pool handle from"]
+ #[doc = " another process."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Multiple calls to this function with the same IPC handle will return"]
+ #[doc = " unique event pool handles."]
+ #[doc = " - The event handle in this process should not be freed with"]
+ #[doc = " ::zeEventPoolDestroy, but rather with ::zeEventPoolCloseIpcHandle."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == phEventPool`"]
+ pub fn zeEventPoolOpenIpcHandle(
+ hContext: ze_context_handle_t,
+ hIpc: ze_ipc_event_pool_handle_t,
+ phEventPool: *mut ze_event_pool_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Closes an IPC event handle in the current process."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Closes an IPC event handle by destroying events that were opened in"]
+ #[doc = " this process using ::zeEventPoolOpenIpcHandle."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same event pool handle."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hEventPool`"]
+ pub fn zeEventPoolCloseIpcHandle(hEventPool: ze_event_pool_handle_t) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Appends a signal of the event from the device into a command list."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the events are accessible by the device on"]
+ #[doc = " which the command list was created."]
+ #[doc = " - The duration of an event created from an event pool that was created"]
+ #[doc = " using ::ZE_EVENT_POOL_FLAG_KERNEL_TIMESTAMP flag is undefined."]
+ #[doc = " However, for consistency and orthogonality the event will report"]
+ #[doc = " correctly as signaled when used by other event API functionality."]
+ #[doc = " - The application must ensure the command list and events were created"]
+ #[doc = " on the same context."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - **clSetUserEventStatus**"]
+ #[doc = " - vkCmdSetEvent"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " + `nullptr == hEvent`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ pub fn zeCommandListAppendSignalEvent(
+ hCommandList: ze_command_list_handle_t,
+ hEvent: ze_event_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Appends wait on event(s) on the device into a command list."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the events are accessible by the device on"]
+ #[doc = " which the command list was created."]
+ #[doc = " - The application must ensure the command list and events were created"]
+ #[doc = " on the same context."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == phEvents`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ pub fn zeCommandListAppendWaitOnEvents(
+ hCommandList: ze_command_list_handle_t,
+ numEvents: u32,
+ phEvents: *mut ze_event_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Signals a event from host."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The duration of an event created from an event pool that was created"]
+ #[doc = " using ::ZE_EVENT_POOL_FLAG_KERNEL_TIMESTAMP flag is undefined."]
+ #[doc = " However, for consistency and orthogonality the event will report"]
+ #[doc = " correctly as signaled when used by other event API functionality."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - clSetUserEventStatus"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hEvent`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ pub fn zeEventHostSignal(hEvent: ze_event_handle_t) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief The current host thread waits on an event to be signaled."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - clWaitForEvents"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hEvent`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_NOT_READY"]
+ #[doc = " + timeout expired"]
+ pub fn zeEventHostSynchronize(hEvent: ze_event_handle_t, timeout: u64) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Queries an event object's status on the host."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - **clGetEventInfo**"]
+ #[doc = " - vkGetEventStatus"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hEvent`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_NOT_READY"]
+ #[doc = " + not signaled"]
+ pub fn zeEventQueryStatus(hEvent: ze_event_handle_t) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Appends a reset of an event back to not signaled state into a command"]
+ #[doc = " list."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the events are accessible by the device on"]
+ #[doc = " which the command list was created."]
+ #[doc = " - The application must ensure the command list and events were created"]
+ #[doc = " on the same context."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - vkResetEvent"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " + `nullptr == hEvent`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ pub fn zeCommandListAppendEventReset(
+ hCommandList: ze_command_list_handle_t,
+ hEvent: ze_event_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief The current host thread resets an event back to not signaled state."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - vkResetEvent"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hEvent`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ pub fn zeEventHostReset(hEvent: ze_event_handle_t) -> ze_result_t;
+}
+#[doc = ""]
+#[doc = " @brief Kernel timestamp clock data"]
+#[doc = ""]
+#[doc = " @details"]
+#[doc = " - The timestamp frequency can be queried from"]
+#[doc = " ::ze_device_properties_t.timerResolution."]
+#[doc = " - The number of valid bits in the timestamp value can be queried from"]
+#[doc = " ::ze_device_properties_t.kernelTimestampValidBits."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_kernel_timestamp_data_t {
+ #[doc = "< [out] device clock at start of kernel execution"]
+ pub kernelStart: u64,
+ #[doc = "< [out] device clock at end of kernel execution"]
+ pub kernelEnd: u64,
+}
+#[test]
+fn bindgen_test_layout__ze_kernel_timestamp_data_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_kernel_timestamp_data_t>(),
+ 16usize,
+ concat!("Size of: ", stringify!(_ze_kernel_timestamp_data_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_kernel_timestamp_data_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_kernel_timestamp_data_t))
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_kernel_timestamp_data_t>())).kernelStart as *const _ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_timestamp_data_t),
+ "::",
+ stringify!(kernelStart)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_kernel_timestamp_data_t>())).kernelEnd as *const _ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_timestamp_data_t),
+ "::",
+ stringify!(kernelEnd)
+ )
+ );
+}
+#[doc = ""]
+#[doc = " @brief Kernel timestamp result"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_kernel_timestamp_result_t {
+ #[doc = "< [out] wall-clock data"]
+ pub global: ze_kernel_timestamp_data_t,
+ #[doc = "< [out] context-active data; only includes clocks while device context"]
+ #[doc = "< was actively executing."]
+ pub context: ze_kernel_timestamp_data_t,
+}
+#[test]
+fn bindgen_test_layout__ze_kernel_timestamp_result_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_kernel_timestamp_result_t>(),
+ 32usize,
+ concat!("Size of: ", stringify!(_ze_kernel_timestamp_result_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_kernel_timestamp_result_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_kernel_timestamp_result_t))
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_kernel_timestamp_result_t>())).global as *const _ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_timestamp_result_t),
+ "::",
+ stringify!(global)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_kernel_timestamp_result_t>())).context as *const _ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_timestamp_result_t),
+ "::",
+ stringify!(context)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Queries an event's timestamp value on the host."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the event was created from an event pool"]
+ #[doc = " that was created using ::ZE_EVENT_POOL_FLAG_KERNEL_TIMESTAMP flag."]
+ #[doc = " - The destination memory will be unmodified if the event has not been"]
+ #[doc = " signaled."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hEvent`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == dstptr`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_NOT_READY"]
+ #[doc = " + not signaled"]
+ pub fn zeEventQueryKernelTimestamp(
+ hEvent: ze_event_handle_t,
+ dstptr: *mut ze_kernel_timestamp_result_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Appends a query of an events' timestamp value(s) into a command list."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the events are accessible by the device on"]
+ #[doc = " which the command list was created."]
+ #[doc = " - The application must ensure the events were created from an event pool"]
+ #[doc = " that was created using ::ZE_EVENT_POOL_FLAG_KERNEL_TIMESTAMP flag."]
+ #[doc = " - The application must ensure the memory pointed to by both dstptr and"]
+ #[doc = " pOffsets is accessible by the device on which the command list was"]
+ #[doc = " created."]
+ #[doc = " - The value(s) written to the destination buffer are undefined if any"]
+ #[doc = " timestamp event has not been signaled."]
+ #[doc = " - If pOffsets is nullptr, then multiple results will be appended"]
+ #[doc = " sequentially into memory in the same order as phEvents."]
+ #[doc = " - The application must ensure the command list and events were created,"]
+ #[doc = " and the memory was allocated, on the same context."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == phEvents`"]
+ #[doc = " + `nullptr == dstptr`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `(nullptr == phWaitEvents) && (0 < numWaitEvents)`"]
+ pub fn zeCommandListAppendQueryKernelTimestamps(
+ hCommandList: ze_command_list_handle_t,
+ numEvents: u32,
+ phEvents: *mut ze_event_handle_t,
+ dstptr: *mut ::std::os::raw::c_void,
+ pOffsets: *const usize,
+ hSignalEvent: ze_event_handle_t,
+ numWaitEvents: u32,
+ phWaitEvents: *mut ze_event_handle_t,
+ ) -> ze_result_t;
+}
+impl _ze_fence_flags_t {
+ #[doc = "< fence is created in the signaled state, otherwise not signaled."]
+ pub const ZE_FENCE_FLAG_SIGNALED: _ze_fence_flags_t = _ze_fence_flags_t(1);
+}
+impl _ze_fence_flags_t {
+ pub const ZE_FENCE_FLAG_FORCE_UINT32: _ze_fence_flags_t = _ze_fence_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_fence_flags_t> for _ze_fence_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_fence_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_fence_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_fence_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_fence_flags_t> for _ze_fence_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_fence_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_fence_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_fence_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported fence creation flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_fence_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported fence creation flags"]
+pub use self::_ze_fence_flags_t as ze_fence_flags_t;
+#[doc = ""]
+#[doc = " @brief Fence descriptor"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_fence_desc_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in][optional] pointer to extension-specific structure"]
+ pub pNext: *const ::std::os::raw::c_void,
+ #[doc = "< [in] creation flags."]
+ #[doc = "< must be 0 (default) or a valid combination of ::ze_fence_flags_t."]
+ pub flags: ze_fence_flags_t,
+}
+#[test]
+fn bindgen_test_layout__ze_fence_desc_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_fence_desc_t>(),
+ 24usize,
+ concat!("Size of: ", stringify!(_ze_fence_desc_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_fence_desc_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_fence_desc_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_fence_desc_t>())).stype as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_fence_desc_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_fence_desc_t>())).pNext as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_fence_desc_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_fence_desc_t>())).flags as *const _ as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_fence_desc_t),
+ "::",
+ stringify!(flags)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Creates a fence for the command queue."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - A fence is a heavyweight synchronization primitive used to communicate"]
+ #[doc = " to the host that command list execution has completed."]
+ #[doc = " - The application must only use the fence for the command queue which"]
+ #[doc = " was provided during creation."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - **vkCreateFence**"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandQueue`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == desc`"]
+ #[doc = " + `nullptr == phFence`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `0x1 < desc->flags`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ pub fn zeFenceCreate(
+ hCommandQueue: ze_command_queue_handle_t,
+ desc: *const ze_fence_desc_t,
+ phFence: *mut ze_fence_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Deletes a fence object."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the device is not currently referencing"]
+ #[doc = " the fence before it is deleted."]
+ #[doc = " - The implementation of this function may immediately free all Host and"]
+ #[doc = " Device allocations associated with this fence."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same fence handle."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - **vkDestroyFence**"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hFence`"]
+ #[doc = " - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE"]
+ pub fn zeFenceDestroy(hFence: ze_fence_handle_t) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief The current host thread waits on a fence to be signaled."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - **vkWaitForFences**"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hFence`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_NOT_READY"]
+ #[doc = " + timeout expired"]
+ pub fn zeFenceHostSynchronize(hFence: ze_fence_handle_t, timeout: u64) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Queries a fence object's status."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - **vkGetFenceStatus**"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hFence`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_NOT_READY"]
+ #[doc = " + not signaled"]
+ pub fn zeFenceQueryStatus(hFence: ze_fence_handle_t) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Reset a fence back to the not signaled state."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - **vkResetFences**"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hFence`"]
+ pub fn zeFenceReset(hFence: ze_fence_handle_t) -> ze_result_t;
+}
+impl _ze_image_flags_t {
+ #[doc = "< kernels will write contents"]
+ pub const ZE_IMAGE_FLAG_KERNEL_WRITE: _ze_image_flags_t = _ze_image_flags_t(1);
+}
+impl _ze_image_flags_t {
+ #[doc = "< device should not cache contents"]
+ pub const ZE_IMAGE_FLAG_BIAS_UNCACHED: _ze_image_flags_t = _ze_image_flags_t(2);
+}
+impl _ze_image_flags_t {
+ pub const ZE_IMAGE_FLAG_FORCE_UINT32: _ze_image_flags_t = _ze_image_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_image_flags_t> for _ze_image_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_image_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_image_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_image_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_image_flags_t> for _ze_image_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_image_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_image_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_image_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported image creation flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_image_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported image creation flags"]
+pub use self::_ze_image_flags_t as ze_image_flags_t;
+impl _ze_image_type_t {
+ #[doc = "< 1D"]
+ pub const ZE_IMAGE_TYPE_1D: _ze_image_type_t = _ze_image_type_t(0);
+}
+impl _ze_image_type_t {
+ #[doc = "< 1D array"]
+ pub const ZE_IMAGE_TYPE_1DARRAY: _ze_image_type_t = _ze_image_type_t(1);
+}
+impl _ze_image_type_t {
+ #[doc = "< 2D"]
+ pub const ZE_IMAGE_TYPE_2D: _ze_image_type_t = _ze_image_type_t(2);
+}
+impl _ze_image_type_t {
+ #[doc = "< 2D array"]
+ pub const ZE_IMAGE_TYPE_2DARRAY: _ze_image_type_t = _ze_image_type_t(3);
+}
+impl _ze_image_type_t {
+ #[doc = "< 3D"]
+ pub const ZE_IMAGE_TYPE_3D: _ze_image_type_t = _ze_image_type_t(4);
+}
+impl _ze_image_type_t {
+ #[doc = "< Buffer"]
+ pub const ZE_IMAGE_TYPE_BUFFER: _ze_image_type_t = _ze_image_type_t(5);
+}
+impl _ze_image_type_t {
+ pub const ZE_IMAGE_TYPE_FORCE_UINT32: _ze_image_type_t = _ze_image_type_t(2147483647);
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported image types"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_image_type_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported image types"]
+pub use self::_ze_image_type_t as ze_image_type_t;
+impl _ze_image_format_layout_t {
+ #[doc = "< 8-bit single component layout"]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_8: _ze_image_format_layout_t = _ze_image_format_layout_t(0);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< 16-bit single component layout"]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_16: _ze_image_format_layout_t = _ze_image_format_layout_t(1);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< 32-bit single component layout"]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_32: _ze_image_format_layout_t = _ze_image_format_layout_t(2);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< 2-component 8-bit layout"]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_8_8: _ze_image_format_layout_t = _ze_image_format_layout_t(3);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< 4-component 8-bit layout"]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_8_8_8_8: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(4);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< 2-component 16-bit layout"]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_16_16: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(5);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< 4-component 16-bit layout"]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_16_16_16_16: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(6);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< 2-component 32-bit layout"]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_32_32: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(7);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< 4-component 32-bit layout"]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_32_32_32_32: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(8);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< 4-component 10_10_10_2 layout"]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_10_10_10_2: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(9);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< 3-component 11_11_10 layout"]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_11_11_10: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(10);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< 3-component 5_6_5 layout"]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_5_6_5: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(11);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< 4-component 5_5_5_1 layout"]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_5_5_5_1: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(12);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< 4-component 4_4_4_4 layout"]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_4_4_4_4: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(13);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< Media Format: Y8. Format type and swizzle is ignored for this."]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_Y8: _ze_image_format_layout_t = _ze_image_format_layout_t(14);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< Media Format: NV12. Format type and swizzle is ignored for this."]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_NV12: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(15);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< Media Format: YUYV. Format type and swizzle is ignored for this."]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_YUYV: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(16);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< Media Format: VYUY. Format type and swizzle is ignored for this."]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_VYUY: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(17);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< Media Format: YVYU. Format type and swizzle is ignored for this."]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_YVYU: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(18);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< Media Format: UYVY. Format type and swizzle is ignored for this."]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_UYVY: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(19);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< Media Format: AYUV. Format type and swizzle is ignored for this."]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_AYUV: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(20);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< Media Format: P010. Format type and swizzle is ignored for this."]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_P010: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(21);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< Media Format: Y410. Format type and swizzle is ignored for this."]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_Y410: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(22);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< Media Format: P012. Format type and swizzle is ignored for this."]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_P012: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(23);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< Media Format: Y16. Format type and swizzle is ignored for this."]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_Y16: _ze_image_format_layout_t = _ze_image_format_layout_t(24);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< Media Format: P016. Format type and swizzle is ignored for this."]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_P016: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(25);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< Media Format: Y216. Format type and swizzle is ignored for this."]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_Y216: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(26);
+}
+impl _ze_image_format_layout_t {
+ #[doc = "< Media Format: P216. Format type and swizzle is ignored for this."]
+ pub const ZE_IMAGE_FORMAT_LAYOUT_P216: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(27);
+}
+impl _ze_image_format_layout_t {
+ pub const ZE_IMAGE_FORMAT_LAYOUT_FORCE_UINT32: _ze_image_format_layout_t =
+ _ze_image_format_layout_t(2147483647);
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported image format layouts"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_image_format_layout_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported image format layouts"]
+pub use self::_ze_image_format_layout_t as ze_image_format_layout_t;
+impl _ze_image_format_type_t {
+ #[doc = "< Unsigned integer"]
+ pub const ZE_IMAGE_FORMAT_TYPE_UINT: _ze_image_format_type_t = _ze_image_format_type_t(0);
+}
+impl _ze_image_format_type_t {
+ #[doc = "< Signed integer"]
+ pub const ZE_IMAGE_FORMAT_TYPE_SINT: _ze_image_format_type_t = _ze_image_format_type_t(1);
+}
+impl _ze_image_format_type_t {
+ #[doc = "< Unsigned normalized integer"]
+ pub const ZE_IMAGE_FORMAT_TYPE_UNORM: _ze_image_format_type_t = _ze_image_format_type_t(2);
+}
+impl _ze_image_format_type_t {
+ #[doc = "< Signed normalized integer"]
+ pub const ZE_IMAGE_FORMAT_TYPE_SNORM: _ze_image_format_type_t = _ze_image_format_type_t(3);
+}
+impl _ze_image_format_type_t {
+ #[doc = "< Float"]
+ pub const ZE_IMAGE_FORMAT_TYPE_FLOAT: _ze_image_format_type_t = _ze_image_format_type_t(4);
+}
+impl _ze_image_format_type_t {
+ pub const ZE_IMAGE_FORMAT_TYPE_FORCE_UINT32: _ze_image_format_type_t =
+ _ze_image_format_type_t(2147483647);
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported image format types"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_image_format_type_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported image format types"]
+pub use self::_ze_image_format_type_t as ze_image_format_type_t;
+impl _ze_image_format_swizzle_t {
+ #[doc = "< Red component"]
+ pub const ZE_IMAGE_FORMAT_SWIZZLE_R: _ze_image_format_swizzle_t = _ze_image_format_swizzle_t(0);
+}
+impl _ze_image_format_swizzle_t {
+ #[doc = "< Green component"]
+ pub const ZE_IMAGE_FORMAT_SWIZZLE_G: _ze_image_format_swizzle_t = _ze_image_format_swizzle_t(1);
+}
+impl _ze_image_format_swizzle_t {
+ #[doc = "< Blue component"]
+ pub const ZE_IMAGE_FORMAT_SWIZZLE_B: _ze_image_format_swizzle_t = _ze_image_format_swizzle_t(2);
+}
+impl _ze_image_format_swizzle_t {
+ #[doc = "< Alpha component"]
+ pub const ZE_IMAGE_FORMAT_SWIZZLE_A: _ze_image_format_swizzle_t = _ze_image_format_swizzle_t(3);
+}
+impl _ze_image_format_swizzle_t {
+ #[doc = "< Zero"]
+ pub const ZE_IMAGE_FORMAT_SWIZZLE_0: _ze_image_format_swizzle_t = _ze_image_format_swizzle_t(4);
+}
+impl _ze_image_format_swizzle_t {
+ #[doc = "< One"]
+ pub const ZE_IMAGE_FORMAT_SWIZZLE_1: _ze_image_format_swizzle_t = _ze_image_format_swizzle_t(5);
+}
+impl _ze_image_format_swizzle_t {
+ #[doc = "< Don't care"]
+ pub const ZE_IMAGE_FORMAT_SWIZZLE_X: _ze_image_format_swizzle_t = _ze_image_format_swizzle_t(6);
+}
+impl _ze_image_format_swizzle_t {
+ pub const ZE_IMAGE_FORMAT_SWIZZLE_FORCE_UINT32: _ze_image_format_swizzle_t =
+ _ze_image_format_swizzle_t(2147483647);
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported image format component swizzle into channel"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_image_format_swizzle_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported image format component swizzle into channel"]
+pub use self::_ze_image_format_swizzle_t as ze_image_format_swizzle_t;
+#[doc = ""]
+#[doc = " @brief Image format"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_image_format_t {
+ #[doc = "< [in] image format component layout"]
+ pub layout: ze_image_format_layout_t,
+ #[doc = "< [in] image format type. Media formats can't be used for"]
+ #[doc = "< ::ZE_IMAGE_TYPE_BUFFER."]
+ pub type_: ze_image_format_type_t,
+ #[doc = "< [in] image component swizzle into channel x"]
+ pub x: ze_image_format_swizzle_t,
+ #[doc = "< [in] image component swizzle into channel y"]
+ pub y: ze_image_format_swizzle_t,
+ #[doc = "< [in] image component swizzle into channel z"]
+ pub z: ze_image_format_swizzle_t,
+ #[doc = "< [in] image component swizzle into channel w"]
+ pub w: ze_image_format_swizzle_t,
+}
+#[test]
+fn bindgen_test_layout__ze_image_format_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_image_format_t>(),
+ 24usize,
+ concat!("Size of: ", stringify!(_ze_image_format_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_image_format_t>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(_ze_image_format_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_format_t>())).layout as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_format_t),
+ "::",
+ stringify!(layout)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_format_t>())).type_ as *const _ as usize },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_format_t),
+ "::",
+ stringify!(type_)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_format_t>())).x as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_format_t),
+ "::",
+ stringify!(x)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_format_t>())).y as *const _ as usize },
+ 12usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_format_t),
+ "::",
+ stringify!(y)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_format_t>())).z as *const _ as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_format_t),
+ "::",
+ stringify!(z)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_format_t>())).w as *const _ as usize },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_format_t),
+ "::",
+ stringify!(w)
+ )
+ );
+}
+#[doc = ""]
+#[doc = " @brief Image descriptor"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_image_desc_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in][optional] pointer to extension-specific structure"]
+ pub pNext: *const ::std::os::raw::c_void,
+ #[doc = "< [in] creation flags."]
+ #[doc = "< must be 0 (default) or a valid combination of ::ze_image_flags_t;"]
+ #[doc = "< default is read-only, cached access."]
+ pub flags: ze_image_flags_t,
+ #[doc = "< [in] image type"]
+ pub type_: ze_image_type_t,
+ #[doc = "< [in] image format"]
+ pub format: ze_image_format_t,
+ #[doc = "< [in] width dimension."]
+ #[doc = "< ::ZE_IMAGE_TYPE_BUFFER: size in bytes; see"]
+ #[doc = "< ::ze_device_image_properties_t.maxImageBufferSize for limits."]
+ #[doc = "< ::ZE_IMAGE_TYPE_1D, ::ZE_IMAGE_TYPE_1DARRAY: width in pixels; see"]
+ #[doc = "< ::ze_device_image_properties_t.maxImageDims1D for limits."]
+ #[doc = "< ::ZE_IMAGE_TYPE_2D, ::ZE_IMAGE_TYPE_2DARRAY: width in pixels; see"]
+ #[doc = "< ::ze_device_image_properties_t.maxImageDims2D for limits."]
+ #[doc = "< ::ZE_IMAGE_TYPE_3D: width in pixels; see"]
+ #[doc = "< ::ze_device_image_properties_t.maxImageDims3D for limits."]
+ pub width: u64,
+ #[doc = "< [in] height dimension."]
+ #[doc = "< ::ZE_IMAGE_TYPE_2D, ::ZE_IMAGE_TYPE_2DARRAY: height in pixels; see"]
+ #[doc = "< ::ze_device_image_properties_t.maxImageDims2D for limits."]
+ #[doc = "< ::ZE_IMAGE_TYPE_3D: height in pixels; see"]
+ #[doc = "< ::ze_device_image_properties_t.maxImageDims3D for limits."]
+ #[doc = "< other: ignored."]
+ pub height: u32,
+ #[doc = "< [in] depth dimension."]
+ #[doc = "< ::ZE_IMAGE_TYPE_3D: depth in pixels; see"]
+ #[doc = "< ::ze_device_image_properties_t.maxImageDims3D for limits."]
+ #[doc = "< other: ignored."]
+ pub depth: u32,
+ #[doc = "< [in] array levels."]
+ #[doc = "< ::ZE_IMAGE_TYPE_1DARRAY, ::ZE_IMAGE_TYPE_2DARRAY: see"]
+ #[doc = "< ::ze_device_image_properties_t.maxImageArraySlices for limits."]
+ #[doc = "< other: ignored."]
+ pub arraylevels: u32,
+ #[doc = "< [in] mipmap levels (must be 0)"]
+ pub miplevels: u32,
+}
+#[test]
+fn bindgen_test_layout__ze_image_desc_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_image_desc_t>(),
+ 72usize,
+ concat!("Size of: ", stringify!(_ze_image_desc_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_image_desc_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_image_desc_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_desc_t>())).stype as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_desc_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_desc_t>())).pNext as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_desc_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_desc_t>())).flags as *const _ as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_desc_t),
+ "::",
+ stringify!(flags)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_desc_t>())).type_ as *const _ as usize },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_desc_t),
+ "::",
+ stringify!(type_)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_desc_t>())).format as *const _ as usize },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_desc_t),
+ "::",
+ stringify!(format)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_desc_t>())).width as *const _ as usize },
+ 48usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_desc_t),
+ "::",
+ stringify!(width)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_desc_t>())).height as *const _ as usize },
+ 56usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_desc_t),
+ "::",
+ stringify!(height)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_desc_t>())).depth as *const _ as usize },
+ 60usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_desc_t),
+ "::",
+ stringify!(depth)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_desc_t>())).arraylevels as *const _ as usize },
+ 64usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_desc_t),
+ "::",
+ stringify!(arraylevels)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_desc_t>())).miplevels as *const _ as usize },
+ 68usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_desc_t),
+ "::",
+ stringify!(miplevels)
+ )
+ );
+}
+impl _ze_image_sampler_filter_flags_t {
+ #[doc = "< device supports point filtering"]
+ pub const ZE_IMAGE_SAMPLER_FILTER_FLAG_POINT: _ze_image_sampler_filter_flags_t =
+ _ze_image_sampler_filter_flags_t(1);
+}
+impl _ze_image_sampler_filter_flags_t {
+ #[doc = "< device supports linear filtering"]
+ pub const ZE_IMAGE_SAMPLER_FILTER_FLAG_LINEAR: _ze_image_sampler_filter_flags_t =
+ _ze_image_sampler_filter_flags_t(2);
+}
+impl _ze_image_sampler_filter_flags_t {
+ pub const ZE_IMAGE_SAMPLER_FILTER_FLAG_FORCE_UINT32: _ze_image_sampler_filter_flags_t =
+ _ze_image_sampler_filter_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_image_sampler_filter_flags_t> for _ze_image_sampler_filter_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_image_sampler_filter_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_image_sampler_filter_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_image_sampler_filter_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_image_sampler_filter_flags_t> for _ze_image_sampler_filter_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_image_sampler_filter_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_image_sampler_filter_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_image_sampler_filter_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported sampler filtering flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_image_sampler_filter_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported sampler filtering flags"]
+pub use self::_ze_image_sampler_filter_flags_t as ze_image_sampler_filter_flags_t;
+#[doc = ""]
+#[doc = " @brief Image properties"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_image_properties_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in,out][optional] pointer to extension-specific structure"]
+ pub pNext: *mut ::std::os::raw::c_void,
+ #[doc = "< [out] supported sampler filtering."]
+ #[doc = "< returns 0 (unsupported) or a combination of ::ze_image_sampler_filter_flags_t."]
+ pub samplerFilterFlags: ze_image_sampler_filter_flags_t,
+}
+#[test]
+fn bindgen_test_layout__ze_image_properties_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_image_properties_t>(),
+ 24usize,
+ concat!("Size of: ", stringify!(_ze_image_properties_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_image_properties_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_image_properties_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_properties_t>())).stype as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_properties_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_image_properties_t>())).pNext as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_properties_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_image_properties_t>())).samplerFilterFlags as *const _
+ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_image_properties_t),
+ "::",
+ stringify!(samplerFilterFlags)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves supported properties of an image."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == desc`"]
+ #[doc = " + `nullptr == pImageProperties`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `0x3 < desc->flags`"]
+ #[doc = " + `::ZE_IMAGE_TYPE_BUFFER < desc->type`"]
+ pub fn zeImageGetProperties(
+ hDevice: ze_device_handle_t,
+ desc: *const ze_image_desc_t,
+ pImageProperties: *mut ze_image_properties_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Creates an image on the context."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must only use the image for the device, or its"]
+ #[doc = " sub-devices, which was provided during creation."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @remarks"]
+ #[doc = " _Analogues_"]
+ #[doc = " - clCreateImage"]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == desc`"]
+ #[doc = " + `nullptr == phImage`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `0x3 < desc->flags`"]
+ #[doc = " + `::ZE_IMAGE_TYPE_BUFFER < desc->type`"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_IMAGE_FORMAT"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ pub fn zeImageCreate(
+ hContext: ze_context_handle_t,
+ hDevice: ze_device_handle_t,
+ desc: *const ze_image_desc_t,
+ phImage: *mut ze_image_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Deletes an image object."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the device is not currently referencing"]
+ #[doc = " the image before it is deleted."]
+ #[doc = " - The implementation of this function may immediately free all Host and"]
+ #[doc = " Device allocations associated with this image."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same image handle."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hImage`"]
+ #[doc = " - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE"]
+ pub fn zeImageDestroy(hImage: ze_image_handle_t) -> ze_result_t;
+}
+impl _ze_device_mem_alloc_flags_t {
+ #[doc = "< device should cache allocation"]
+ pub const ZE_DEVICE_MEM_ALLOC_FLAG_BIAS_CACHED: _ze_device_mem_alloc_flags_t =
+ _ze_device_mem_alloc_flags_t(1);
+}
+impl _ze_device_mem_alloc_flags_t {
+ #[doc = "< device should not cache allocation (UC)"]
+ pub const ZE_DEVICE_MEM_ALLOC_FLAG_BIAS_UNCACHED: _ze_device_mem_alloc_flags_t =
+ _ze_device_mem_alloc_flags_t(2);
+}
+impl _ze_device_mem_alloc_flags_t {
+ pub const ZE_DEVICE_MEM_ALLOC_FLAG_FORCE_UINT32: _ze_device_mem_alloc_flags_t =
+ _ze_device_mem_alloc_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_device_mem_alloc_flags_t> for _ze_device_mem_alloc_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_device_mem_alloc_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_device_mem_alloc_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_device_mem_alloc_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_device_mem_alloc_flags_t> for _ze_device_mem_alloc_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_device_mem_alloc_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_device_mem_alloc_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_device_mem_alloc_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported memory allocation flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_device_mem_alloc_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported memory allocation flags"]
+pub use self::_ze_device_mem_alloc_flags_t as ze_device_mem_alloc_flags_t;
+#[doc = ""]
+#[doc = " @brief Device memory allocation descriptor"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_device_mem_alloc_desc_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in][optional] pointer to extension-specific structure"]
+ pub pNext: *const ::std::os::raw::c_void,
+ #[doc = "< [in] flags specifying additional allocation controls."]
+ #[doc = "< must be 0 (default) or a valid combination of ::ze_device_mem_alloc_flags_t;"]
+ #[doc = "< default behavior may use implicit driver-based heuristics."]
+ pub flags: ze_device_mem_alloc_flags_t,
+ #[doc = "< [in] ordinal of the device's local memory to allocate from."]
+ #[doc = "< must be less than the count returned from ::zeDeviceGetMemoryProperties."]
+ pub ordinal: u32,
+}
+#[test]
+fn bindgen_test_layout__ze_device_mem_alloc_desc_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_device_mem_alloc_desc_t>(),
+ 24usize,
+ concat!("Size of: ", stringify!(_ze_device_mem_alloc_desc_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_device_mem_alloc_desc_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_device_mem_alloc_desc_t))
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_mem_alloc_desc_t>())).stype as *const _ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_mem_alloc_desc_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_mem_alloc_desc_t>())).pNext as *const _ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_mem_alloc_desc_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_mem_alloc_desc_t>())).flags as *const _ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_mem_alloc_desc_t),
+ "::",
+ stringify!(flags)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_device_mem_alloc_desc_t>())).ordinal as *const _ as usize
+ },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_device_mem_alloc_desc_t),
+ "::",
+ stringify!(ordinal)
+ )
+ );
+}
+impl _ze_host_mem_alloc_flags_t {
+ #[doc = "< host should cache allocation"]
+ pub const ZE_HOST_MEM_ALLOC_FLAG_BIAS_CACHED: _ze_host_mem_alloc_flags_t =
+ _ze_host_mem_alloc_flags_t(1);
+}
+impl _ze_host_mem_alloc_flags_t {
+ #[doc = "< host should not cache allocation (UC)"]
+ pub const ZE_HOST_MEM_ALLOC_FLAG_BIAS_UNCACHED: _ze_host_mem_alloc_flags_t =
+ _ze_host_mem_alloc_flags_t(2);
+}
+impl _ze_host_mem_alloc_flags_t {
+ #[doc = "< host memory should be allocated write-combined (WC)"]
+ pub const ZE_HOST_MEM_ALLOC_FLAG_BIAS_WRITE_COMBINED: _ze_host_mem_alloc_flags_t =
+ _ze_host_mem_alloc_flags_t(4);
+}
+impl _ze_host_mem_alloc_flags_t {
+ pub const ZE_HOST_MEM_ALLOC_FLAG_FORCE_UINT32: _ze_host_mem_alloc_flags_t =
+ _ze_host_mem_alloc_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_host_mem_alloc_flags_t> for _ze_host_mem_alloc_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_host_mem_alloc_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_host_mem_alloc_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_host_mem_alloc_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_host_mem_alloc_flags_t> for _ze_host_mem_alloc_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_host_mem_alloc_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_host_mem_alloc_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_host_mem_alloc_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported host memory allocation flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_host_mem_alloc_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported host memory allocation flags"]
+pub use self::_ze_host_mem_alloc_flags_t as ze_host_mem_alloc_flags_t;
+#[doc = ""]
+#[doc = " @brief Host memory allocation descriptor"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_host_mem_alloc_desc_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in][optional] pointer to extension-specific structure"]
+ pub pNext: *const ::std::os::raw::c_void,
+ #[doc = "< [in] flags specifying additional allocation controls."]
+ #[doc = "< must be 0 (default) or a valid combination of ::ze_host_mem_alloc_flags_t;"]
+ #[doc = "< default behavior may use implicit driver-based heuristics."]
+ pub flags: ze_host_mem_alloc_flags_t,
+}
+#[test]
+fn bindgen_test_layout__ze_host_mem_alloc_desc_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_host_mem_alloc_desc_t>(),
+ 24usize,
+ concat!("Size of: ", stringify!(_ze_host_mem_alloc_desc_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_host_mem_alloc_desc_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_host_mem_alloc_desc_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_host_mem_alloc_desc_t>())).stype as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_host_mem_alloc_desc_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_host_mem_alloc_desc_t>())).pNext as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_host_mem_alloc_desc_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_host_mem_alloc_desc_t>())).flags as *const _ as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_host_mem_alloc_desc_t),
+ "::",
+ stringify!(flags)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Allocates shared memory on the context."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Shared allocations share ownership between the host and one or more"]
+ #[doc = " devices."]
+ #[doc = " - Shared allocations may optionally be associated with a device by"]
+ #[doc = " passing a handle to the device."]
+ #[doc = " - Devices supporting only single-device shared access capabilities may"]
+ #[doc = " access shared memory associated with the device."]
+ #[doc = " For these devices, ownership of the allocation is shared between the"]
+ #[doc = " host and the associated device only."]
+ #[doc = " - Passing nullptr as the device handle does not associate the shared"]
+ #[doc = " allocation with any device."]
+ #[doc = " For allocations with no associated device, ownership of the allocation"]
+ #[doc = " is shared between the host and all devices supporting cross-device"]
+ #[doc = " shared access capabilities."]
+ #[doc = " - The application must only use the memory allocation for the context"]
+ #[doc = " and device, or its sub-devices, which was provided during allocation."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == device_desc`"]
+ #[doc = " + `nullptr == host_desc`"]
+ #[doc = " + `nullptr == pptr`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `0x3 < device_desc->flags`"]
+ #[doc = " + `0x7 < host_desc->flags`"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE"]
+ #[doc = " + `0 == size`"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT"]
+ #[doc = " + Must be zero or a power-of-two"]
+ #[doc = " + `0 != (alignment & (alignment - 1))`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ pub fn zeMemAllocShared(
+ hContext: ze_context_handle_t,
+ device_desc: *const ze_device_mem_alloc_desc_t,
+ host_desc: *const ze_host_mem_alloc_desc_t,
+ size: usize,
+ alignment: usize,
+ hDevice: ze_device_handle_t,
+ pptr: *mut *mut ::std::os::raw::c_void,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Allocates device memory on the context."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Device allocations are owned by a specific device."]
+ #[doc = " - In general, a device allocation may only be accessed by the device"]
+ #[doc = " that owns it."]
+ #[doc = " - The application must only use the memory allocation for the context"]
+ #[doc = " and device, or its sub-devices, which was provided during allocation."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == device_desc`"]
+ #[doc = " + `nullptr == pptr`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `0x3 < device_desc->flags`"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE"]
+ #[doc = " + `0 == size`"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT"]
+ #[doc = " + Must be zero or a power-of-two"]
+ #[doc = " + `0 != (alignment & (alignment - 1))`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ pub fn zeMemAllocDevice(
+ hContext: ze_context_handle_t,
+ device_desc: *const ze_device_mem_alloc_desc_t,
+ size: usize,
+ alignment: usize,
+ hDevice: ze_device_handle_t,
+ pptr: *mut *mut ::std::os::raw::c_void,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Allocates host memory on the context."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Host allocations are owned by the host process."]
+ #[doc = " - Host allocations are accessible by the host and all devices within the"]
+ #[doc = " driver's context."]
+ #[doc = " - Host allocations are frequently used as staging areas to transfer data"]
+ #[doc = " to or from devices."]
+ #[doc = " - The application must only use the memory allocation for the context"]
+ #[doc = " which was provided during allocation."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == host_desc`"]
+ #[doc = " + `nullptr == pptr`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `0x7 < host_desc->flags`"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE"]
+ #[doc = " + `0 == size`"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT"]
+ #[doc = " + Must be zero or a power-of-two"]
+ #[doc = " + `0 != (alignment & (alignment - 1))`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ pub fn zeMemAllocHost(
+ hContext: ze_context_handle_t,
+ host_desc: *const ze_host_mem_alloc_desc_t,
+ size: usize,
+ alignment: usize,
+ pptr: *mut *mut ::std::os::raw::c_void,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Frees allocated host memory, device memory, or shared memory on the"]
+ #[doc = " context."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the device is not currently referencing"]
+ #[doc = " the memory before it is freed"]
+ #[doc = " - The implementation of this function may immediately free all Host and"]
+ #[doc = " Device allocations associated with this memory"]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same pointer."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == ptr`"]
+ pub fn zeMemFree(
+ hContext: ze_context_handle_t,
+ ptr: *mut ::std::os::raw::c_void,
+ ) -> ze_result_t;
+}
+impl _ze_memory_type_t {
+ #[doc = "< the memory pointed to is of unknown type"]
+ pub const ZE_MEMORY_TYPE_UNKNOWN: _ze_memory_type_t = _ze_memory_type_t(0);
+}
+impl _ze_memory_type_t {
+ #[doc = "< the memory pointed to is a host allocation"]
+ pub const ZE_MEMORY_TYPE_HOST: _ze_memory_type_t = _ze_memory_type_t(1);
+}
+impl _ze_memory_type_t {
+ #[doc = "< the memory pointed to is a device allocation"]
+ pub const ZE_MEMORY_TYPE_DEVICE: _ze_memory_type_t = _ze_memory_type_t(2);
+}
+impl _ze_memory_type_t {
+ #[doc = "< the memory pointed to is a shared ownership allocation"]
+ pub const ZE_MEMORY_TYPE_SHARED: _ze_memory_type_t = _ze_memory_type_t(3);
+}
+impl _ze_memory_type_t {
+ pub const ZE_MEMORY_TYPE_FORCE_UINT32: _ze_memory_type_t = _ze_memory_type_t(2147483647);
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Memory allocation type"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_memory_type_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Memory allocation type"]
+pub use self::_ze_memory_type_t as ze_memory_type_t;
+#[doc = ""]
+#[doc = " @brief Memory allocation properties queried using ::zeMemGetAllocProperties"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_memory_allocation_properties_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in,out][optional] pointer to extension-specific structure"]
+ pub pNext: *mut ::std::os::raw::c_void,
+ #[doc = "< [out] type of allocated memory"]
+ pub type_: ze_memory_type_t,
+ #[doc = "< [out] identifier for this allocation"]
+ pub id: u64,
+ #[doc = "< [out] page size used for allocation"]
+ pub pageSize: u64,
+}
+#[test]
+fn bindgen_test_layout__ze_memory_allocation_properties_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_memory_allocation_properties_t>(),
+ 40usize,
+ concat!("Size of: ", stringify!(_ze_memory_allocation_properties_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_memory_allocation_properties_t>(),
+ 8usize,
+ concat!(
+ "Alignment of ",
+ stringify!(_ze_memory_allocation_properties_t)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_memory_allocation_properties_t>())).stype as *const _
+ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_memory_allocation_properties_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_memory_allocation_properties_t>())).pNext as *const _
+ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_memory_allocation_properties_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_memory_allocation_properties_t>())).type_ as *const _
+ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_memory_allocation_properties_t),
+ "::",
+ stringify!(type_)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_memory_allocation_properties_t>())).id as *const _ as usize
+ },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_memory_allocation_properties_t),
+ "::",
+ stringify!(id)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_memory_allocation_properties_t>())).pageSize as *const _
+ as usize
+ },
+ 32usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_memory_allocation_properties_t),
+ "::",
+ stringify!(pageSize)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves attributes of a memory allocation"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The application may query attributes of a memory allocation unrelated"]
+ #[doc = " to the context."]
+ #[doc = " When this occurs, the returned allocation type will be"]
+ #[doc = " ::ZE_MEMORY_TYPE_UNKNOWN, and the returned identifier and associated"]
+ #[doc = " device is unspecified."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == ptr`"]
+ #[doc = " + `nullptr == pMemAllocProperties`"]
+ pub fn zeMemGetAllocProperties(
+ hContext: ze_context_handle_t,
+ ptr: *const ::std::os::raw::c_void,
+ pMemAllocProperties: *mut ze_memory_allocation_properties_t,
+ phDevice: *mut ze_device_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves the base address and/or size of an allocation"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == ptr`"]
+ pub fn zeMemGetAddressRange(
+ hContext: ze_context_handle_t,
+ ptr: *const ::std::os::raw::c_void,
+ pBase: *mut *mut ::std::os::raw::c_void,
+ pSize: *mut usize,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Creates an IPC memory handle for the specified allocation"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Takes a pointer to a device memory allocation and creates an IPC"]
+ #[doc = " memory handle for exporting it for use in another process."]
+ #[doc = " - The pointer must be base pointer of the device memory allocation; i.e."]
+ #[doc = " the value returned from ::zeMemAllocDevice."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == ptr`"]
+ #[doc = " + `nullptr == pIpcHandle`"]
+ pub fn zeMemGetIpcHandle(
+ hContext: ze_context_handle_t,
+ ptr: *const ::std::os::raw::c_void,
+ pIpcHandle: *mut ze_ipc_mem_handle_t,
+ ) -> ze_result_t;
+}
+impl _ze_ipc_memory_flags_t {
+ #[doc = "< reserved for future use"]
+ pub const ZE_IPC_MEMORY_FLAG_TBD: _ze_ipc_memory_flags_t = _ze_ipc_memory_flags_t(1);
+}
+impl _ze_ipc_memory_flags_t {
+ pub const ZE_IPC_MEMORY_FLAG_FORCE_UINT32: _ze_ipc_memory_flags_t =
+ _ze_ipc_memory_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_ipc_memory_flags_t> for _ze_ipc_memory_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_ipc_memory_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_ipc_memory_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_ipc_memory_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_ipc_memory_flags_t> for _ze_ipc_memory_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_ipc_memory_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_ipc_memory_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_ipc_memory_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported IPC memory flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_ipc_memory_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported IPC memory flags"]
+pub use self::_ze_ipc_memory_flags_t as ze_ipc_memory_flags_t;
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Opens an IPC memory handle to retrieve a device pointer on the"]
+ #[doc = " context."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Takes an IPC memory handle from a remote process and associates it"]
+ #[doc = " with a device pointer usable in this process."]
+ #[doc = " - The device pointer in this process should not be freed with"]
+ #[doc = " ::zeMemFree, but rather with ::zeMemCloseIpcHandle."]
+ #[doc = " - Multiple calls to this function with the same IPC handle will return"]
+ #[doc = " unique pointers."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `0x1 < flags`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pptr`"]
+ pub fn zeMemOpenIpcHandle(
+ hContext: ze_context_handle_t,
+ hDevice: ze_device_handle_t,
+ handle: ze_ipc_mem_handle_t,
+ flags: ze_ipc_memory_flags_t,
+ pptr: *mut *mut ::std::os::raw::c_void,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Closes an IPC memory handle"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Closes an IPC memory handle by unmapping memory that was opened in"]
+ #[doc = " this process using ::zeMemOpenIpcHandle."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same pointer."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == ptr`"]
+ pub fn zeMemCloseIpcHandle(
+ hContext: ze_context_handle_t,
+ ptr: *const ::std::os::raw::c_void,
+ ) -> ze_result_t;
+}
+impl _ze_module_format_t {
+ #[doc = "< Format is SPIRV IL format"]
+ pub const ZE_MODULE_FORMAT_IL_SPIRV: _ze_module_format_t = _ze_module_format_t(0);
+}
+impl _ze_module_format_t {
+ #[doc = "< Format is device native format"]
+ pub const ZE_MODULE_FORMAT_NATIVE: _ze_module_format_t = _ze_module_format_t(1);
+}
+impl _ze_module_format_t {
+ pub const ZE_MODULE_FORMAT_FORCE_UINT32: _ze_module_format_t = _ze_module_format_t(2147483647);
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported module creation input formats"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_module_format_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported module creation input formats"]
+pub use self::_ze_module_format_t as ze_module_format_t;
+#[doc = ""]
+#[doc = " @brief Specialization constants - User defined constants"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_module_constants_t {
+ #[doc = "< [in] Number of specialization constants."]
+ pub numConstants: u32,
+ #[doc = "< [in][range(0, numConstants)] Array of IDs that is sized to"]
+ #[doc = "< numConstants."]
+ pub pConstantIds: *const u32,
+ #[doc = "< [in][range(0, numConstants)] Array of pointers to values that is sized"]
+ #[doc = "< to numConstants."]
+ pub pConstantValues: *mut *const ::std::os::raw::c_void,
+}
+#[test]
+fn bindgen_test_layout__ze_module_constants_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_module_constants_t>(),
+ 24usize,
+ concat!("Size of: ", stringify!(_ze_module_constants_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_module_constants_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_module_constants_t))
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_module_constants_t>())).numConstants as *const _ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_module_constants_t),
+ "::",
+ stringify!(numConstants)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_module_constants_t>())).pConstantIds as *const _ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_module_constants_t),
+ "::",
+ stringify!(pConstantIds)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_module_constants_t>())).pConstantValues as *const _ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_module_constants_t),
+ "::",
+ stringify!(pConstantValues)
+ )
+ );
+}
+#[doc = ""]
+#[doc = " @brief Module descriptor"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_module_desc_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in][optional] pointer to extension-specific structure"]
+ pub pNext: *const ::std::os::raw::c_void,
+ #[doc = "< [in] Module format passed in with pInputModule"]
+ pub format: ze_module_format_t,
+ #[doc = "< [in] size of input IL or ISA from pInputModule."]
+ pub inputSize: usize,
+ #[doc = "< [in] pointer to IL or ISA"]
+ pub pInputModule: *const u8,
+ #[doc = "< [in][optional] string containing compiler flags. Following options are supported."]
+ #[doc = "< - \"-ze-opt-disable\""]
+ #[doc = "< - Disable optimizations"]
+ #[doc = "< - \"-ze-opt-greater-than-4GB-buffer-required\""]
+ #[doc = "< - Use 64-bit offset calculations for buffers."]
+ #[doc = "< - \"-ze-opt-large-register-file\""]
+ #[doc = "< - Increase number of registers available to threads."]
+ #[doc = "< - \"-ze-opt-has-buffer-offset-arg\""]
+ #[doc = "< - Extend stateless to stateful optimization to more"]
+ #[doc = "< cases with the use of additional offset (e.g. 64-bit"]
+ #[doc = "< pointer to binding table with 32-bit offset)."]
+ #[doc = "< - \"-g\""]
+ #[doc = "< - Include debugging information."]
+ pub pBuildFlags: *const ::std::os::raw::c_char,
+ #[doc = "< [in][optional] pointer to specialization constants. Valid only for"]
+ #[doc = "< SPIR-V input. This must be set to nullptr if no specialization"]
+ #[doc = "< constants are provided."]
+ pub pConstants: *const ze_module_constants_t,
+}
+#[test]
+fn bindgen_test_layout__ze_module_desc_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_module_desc_t>(),
+ 56usize,
+ concat!("Size of: ", stringify!(_ze_module_desc_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_module_desc_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_module_desc_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_module_desc_t>())).stype as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_module_desc_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_module_desc_t>())).pNext as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_module_desc_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_module_desc_t>())).format as *const _ as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_module_desc_t),
+ "::",
+ stringify!(format)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_module_desc_t>())).inputSize as *const _ as usize },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_module_desc_t),
+ "::",
+ stringify!(inputSize)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_module_desc_t>())).pInputModule as *const _ as usize },
+ 32usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_module_desc_t),
+ "::",
+ stringify!(pInputModule)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_module_desc_t>())).pBuildFlags as *const _ as usize },
+ 40usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_module_desc_t),
+ "::",
+ stringify!(pBuildFlags)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_module_desc_t>())).pConstants as *const _ as usize },
+ 48usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_module_desc_t),
+ "::",
+ stringify!(pConstants)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Creates a module on the context."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Compiles the module for execution on the device."]
+ #[doc = " - The application must only use the module for the device, or its"]
+ #[doc = " sub-devices, which was provided during creation."]
+ #[doc = " - The module can be copied to other devices and contexts within the same"]
+ #[doc = " driver instance by using ::zeModuleGetNativeBinary."]
+ #[doc = " - A build log can optionally be returned to the caller. The caller is"]
+ #[doc = " responsible for destroying build log using ::zeModuleBuildLogDestroy."]
+ #[doc = " - The module descriptor constants are only supported for SPIR-V"]
+ #[doc = " specialization constants."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == desc`"]
+ #[doc = " + `nullptr == desc->pInputModule`"]
+ #[doc = " + `nullptr == phModule`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `::ZE_MODULE_FORMAT_NATIVE < desc->format`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NATIVE_BINARY"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `0 == desc->inputSize`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_MODULE_BUILD_FAILURE"]
+ pub fn zeModuleCreate(
+ hContext: ze_context_handle_t,
+ hDevice: ze_device_handle_t,
+ desc: *const ze_module_desc_t,
+ phModule: *mut ze_module_handle_t,
+ phBuildLog: *mut ze_module_build_log_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Destroys module"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must destroy all kernel and build log handles created"]
+ #[doc = " from the module before destroying the module itself."]
+ #[doc = " - The application must ensure the device is not currently referencing"]
+ #[doc = " the module before it is deleted."]
+ #[doc = " - The implementation of this function may immediately free all Host and"]
+ #[doc = " Device allocations associated with this module."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same module handle."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hModule`"]
+ #[doc = " - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE"]
+ pub fn zeModuleDestroy(hModule: ze_module_handle_t) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Dynamically link modules together that share import/export linkage"]
+ #[doc = " dependencies."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Modules support import and export linkage for functions and global"]
+ #[doc = " variables."]
+ #[doc = " - Modules that have imports can be dynamically linked to export modules"]
+ #[doc = " that satisfy those import requirements."]
+ #[doc = " - Modules can have both import and export linkages."]
+ #[doc = " - Modules that do not have any imports or exports do not need to be"]
+ #[doc = " linked."]
+ #[doc = " - Modules cannot be partially linked. All modules needed to satisfy all"]
+ #[doc = " import dependencies for a module must be passed in or"]
+ #[doc = " ::ZE_RESULT_ERROR_MODULE_LINK_FAILURE will returned."]
+ #[doc = " - Modules with imports need to be linked before kernel objects can be"]
+ #[doc = " created from them."]
+ #[doc = " - Modules will only be linked once. A module can be used in multiple"]
+ #[doc = " link calls if it has exports but it's imports will not be re-linked."]
+ #[doc = " - Ambiguous dependencies, where multiple modules satisfy the import"]
+ #[doc = " dependencies for another module, is not allowed."]
+ #[doc = " - ModuleGetNativeBinary can be called on any module regardless of"]
+ #[doc = " whether it is linked or not."]
+ #[doc = " - A link log can optionally be returned to the caller. The caller is"]
+ #[doc = " responsible for destroying build log using ::zeModuleBuildLogDestroy."]
+ #[doc = " - See SPIR-V specification for linkage details."]
+ #[doc = " - The application may call this function from simultaneous threads as"]
+ #[doc = " long as the import modules being linked are not the same."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == phModules`"]
+ #[doc = " - ::ZE_RESULT_ERROR_MODULE_LINK_FAILURE"]
+ pub fn zeModuleDynamicLink(
+ numModules: u32,
+ phModules: *mut ze_module_handle_t,
+ phLinkLog: *mut ze_module_build_log_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Destroys module build log object"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The implementation of this function may immediately free all Host"]
+ #[doc = " allocations associated with this object."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same build log handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = " - This function can be called before or after ::zeModuleDestroy for the"]
+ #[doc = " associated module."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hModuleBuildLog`"]
+ #[doc = " - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE"]
+ pub fn zeModuleBuildLogDestroy(hModuleBuildLog: ze_module_build_log_handle_t) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieves text string for build log."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The caller can pass nullptr for pBuildLog when querying only for size."]
+ #[doc = " - The caller must provide memory for build log."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hModuleBuildLog`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pSize`"]
+ pub fn zeModuleBuildLogGetString(
+ hModuleBuildLog: ze_module_build_log_handle_t,
+ pSize: *mut usize,
+ pBuildLog: *mut ::std::os::raw::c_char,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieve native binary from Module."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The native binary output can be cached to disk and new modules can be"]
+ #[doc = " later constructed from the cached copy."]
+ #[doc = " - The native binary will retain debugging information that is associated"]
+ #[doc = " with a module."]
+ #[doc = " - The caller can pass nullptr for pModuleNativeBinary when querying only"]
+ #[doc = " for size."]
+ #[doc = " - The implementation will copy the native binary into a buffer supplied"]
+ #[doc = " by the caller."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hModule`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pSize`"]
+ pub fn zeModuleGetNativeBinary(
+ hModule: ze_module_handle_t,
+ pSize: *mut usize,
+ pModuleNativeBinary: *mut u8,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieve global variable pointer from Module."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may query global pointer from any module that either"]
+ #[doc = " exports or imports it."]
+ #[doc = " - The application must dynamically link a module that imports a global"]
+ #[doc = " before the global pointer can be queried from it."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hModule`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pGlobalName`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_GLOBAL_NAME"]
+ pub fn zeModuleGetGlobalPointer(
+ hModule: ze_module_handle_t,
+ pGlobalName: *const ::std::os::raw::c_char,
+ pSize: *mut usize,
+ pptr: *mut *mut ::std::os::raw::c_void,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieve all kernel names in the module."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hModule`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pCount`"]
+ pub fn zeModuleGetKernelNames(
+ hModule: ze_module_handle_t,
+ pCount: *mut u32,
+ pNames: *mut *const ::std::os::raw::c_char,
+ ) -> ze_result_t;
+}
+impl _ze_module_property_flags_t {
+ #[doc = "< Module has imports (i.e. imported global variables and/or kernels)."]
+ #[doc = "< See ::zeModuleDynamicLink."]
+ pub const ZE_MODULE_PROPERTY_FLAG_IMPORTS: _ze_module_property_flags_t =
+ _ze_module_property_flags_t(1);
+}
+impl _ze_module_property_flags_t {
+ pub const ZE_MODULE_PROPERTY_FLAG_FORCE_UINT32: _ze_module_property_flags_t =
+ _ze_module_property_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_module_property_flags_t> for _ze_module_property_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_module_property_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_module_property_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_module_property_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_module_property_flags_t> for _ze_module_property_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_module_property_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_module_property_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_module_property_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported module property flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_module_property_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported module property flags"]
+pub use self::_ze_module_property_flags_t as ze_module_property_flags_t;
+#[doc = ""]
+#[doc = " @brief Module properties"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_module_properties_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in,out][optional] pointer to extension-specific structure"]
+ pub pNext: *mut ::std::os::raw::c_void,
+ #[doc = "< [out] 0 (none) or a valid combination of ::ze_module_property_flags_t"]
+ pub flags: ze_module_property_flags_t,
+}
+#[test]
+fn bindgen_test_layout__ze_module_properties_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_module_properties_t>(),
+ 24usize,
+ concat!("Size of: ", stringify!(_ze_module_properties_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_module_properties_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_module_properties_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_module_properties_t>())).stype as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_module_properties_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_module_properties_t>())).pNext as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_module_properties_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_module_properties_t>())).flags as *const _ as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_module_properties_t),
+ "::",
+ stringify!(flags)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieve module properties."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hModule`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pModuleProperties`"]
+ pub fn zeModuleGetProperties(
+ hModule: ze_module_handle_t,
+ pModuleProperties: *mut ze_module_properties_t,
+ ) -> ze_result_t;
+}
+impl _ze_kernel_flags_t {
+ #[doc = "< force all device allocations to be resident during execution"]
+ pub const ZE_KERNEL_FLAG_FORCE_RESIDENCY: _ze_kernel_flags_t = _ze_kernel_flags_t(1);
+}
+impl _ze_kernel_flags_t {
+ #[doc = "< application is responsible for all residency of device allocations."]
+ #[doc = "< driver may disable implicit residency management."]
+ pub const ZE_KERNEL_FLAG_EXPLICIT_RESIDENCY: _ze_kernel_flags_t = _ze_kernel_flags_t(2);
+}
+impl _ze_kernel_flags_t {
+ pub const ZE_KERNEL_FLAG_FORCE_UINT32: _ze_kernel_flags_t = _ze_kernel_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_kernel_flags_t> for _ze_kernel_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_kernel_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_kernel_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_kernel_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_kernel_flags_t> for _ze_kernel_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_kernel_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_kernel_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_kernel_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported kernel creation flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_kernel_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported kernel creation flags"]
+pub use self::_ze_kernel_flags_t as ze_kernel_flags_t;
+#[doc = ""]
+#[doc = " @brief Kernel descriptor"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_kernel_desc_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in][optional] pointer to extension-specific structure"]
+ pub pNext: *const ::std::os::raw::c_void,
+ #[doc = "< [in] creation flags."]
+ #[doc = "< must be 0 (default) or a valid combination of ::ze_kernel_flags_t;"]
+ #[doc = "< default behavior may use driver-based residency."]
+ pub flags: ze_kernel_flags_t,
+ #[doc = "< [in] null-terminated name of kernel in module"]
+ pub pKernelName: *const ::std::os::raw::c_char,
+}
+#[test]
+fn bindgen_test_layout__ze_kernel_desc_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_kernel_desc_t>(),
+ 32usize,
+ concat!("Size of: ", stringify!(_ze_kernel_desc_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_kernel_desc_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_kernel_desc_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_kernel_desc_t>())).stype as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_desc_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_kernel_desc_t>())).pNext as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_desc_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_kernel_desc_t>())).flags as *const _ as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_desc_t),
+ "::",
+ stringify!(flags)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_kernel_desc_t>())).pKernelName as *const _ as usize },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_desc_t),
+ "::",
+ stringify!(pKernelName)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Create a kernel from the module."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Modules that have unresolved imports need to be dynamically linked"]
+ #[doc = " before a kernel can be created from them. (See ::zeModuleDynamicLink)"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hModule`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == desc`"]
+ #[doc = " + `nullptr == desc->pKernelName`"]
+ #[doc = " + `nullptr == phKernel`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `0x3 < desc->flags`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_KERNEL_NAME"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_MODULE_UNLINKED"]
+ pub fn zeKernelCreate(
+ hModule: ze_module_handle_t,
+ desc: *const ze_kernel_desc_t,
+ phKernel: *mut ze_kernel_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Destroys a kernel object"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the device is not currently referencing"]
+ #[doc = " the kernel before it is deleted."]
+ #[doc = " - The implementation of this function may immediately free all Host and"]
+ #[doc = " Device allocations associated with this kernel."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same kernel handle."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hKernel`"]
+ #[doc = " - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE"]
+ pub fn zeKernelDestroy(hKernel: ze_kernel_handle_t) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieve a function pointer from a module by name"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The function pointer is unique for the device on which the module was"]
+ #[doc = " created."]
+ #[doc = " - The function pointer is no longer valid if module is destroyed."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hModule`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pFunctionName`"]
+ #[doc = " + `nullptr == pfnFunction`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_FUNCTION_NAME"]
+ pub fn zeModuleGetFunctionPointer(
+ hModule: ze_module_handle_t,
+ pFunctionName: *const ::std::os::raw::c_char,
+ pfnFunction: *mut *mut ::std::os::raw::c_void,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Set group size for a kernel on the current Host thread."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The implementation will maintain the group size in thread-local"]
+ #[doc = " storage."]
+ #[doc = " - The group size will be used when a ::zeCommandListAppendLaunchKernel"]
+ #[doc = " variant is called on the same Host thread."]
+ #[doc = " - The application may call this function from simultaneous threads with"]
+ #[doc = " the same kernel handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hKernel`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_GROUP_SIZE_DIMENSION"]
+ pub fn zeKernelSetGroupSize(
+ hKernel: ze_kernel_handle_t,
+ groupSizeX: u32,
+ groupSizeY: u32,
+ groupSizeZ: u32,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Query a suggested group size for a kernel given a global size for each"]
+ #[doc = " dimension."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - This function ignores the group size that is set using"]
+ #[doc = " ::zeKernelSetGroupSize."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hKernel`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == groupSizeX`"]
+ #[doc = " + `nullptr == groupSizeY`"]
+ #[doc = " + `nullptr == groupSizeZ`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_GLOBAL_WIDTH_DIMENSION"]
+ pub fn zeKernelSuggestGroupSize(
+ hKernel: ze_kernel_handle_t,
+ globalSizeX: u32,
+ globalSizeY: u32,
+ globalSizeZ: u32,
+ groupSizeX: *mut u32,
+ groupSizeY: *mut u32,
+ groupSizeZ: *mut u32,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Query a suggested max group count for a cooperative kernel."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hKernel`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == totalGroupCount`"]
+ pub fn zeKernelSuggestMaxCooperativeGroupCount(
+ hKernel: ze_kernel_handle_t,
+ totalGroupCount: *mut u32,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Set kernel argument for a kernel on the current Host thread."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The implementation will maintain the argument values in thread-local"]
+ #[doc = " storage."]
+ #[doc = " - The argument values will be used when a"]
+ #[doc = " ::zeCommandListAppendLaunchKernel variant is called on the same Host"]
+ #[doc = " thread."]
+ #[doc = " - The application may call this function from simultaneous threads with"]
+ #[doc = " the same kernel handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hKernel`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_INDEX"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_SIZE"]
+ pub fn zeKernelSetArgumentValue(
+ hKernel: ze_kernel_handle_t,
+ argIndex: u32,
+ argSize: usize,
+ pArgValue: *const ::std::os::raw::c_void,
+ ) -> ze_result_t;
+}
+impl _ze_kernel_indirect_access_flags_t {
+ #[doc = "< Indicates that the kernel accesses host allocations indirectly."]
+ pub const ZE_KERNEL_INDIRECT_ACCESS_FLAG_HOST: _ze_kernel_indirect_access_flags_t =
+ _ze_kernel_indirect_access_flags_t(1);
+}
+impl _ze_kernel_indirect_access_flags_t {
+ #[doc = "< Indicates that the kernel accesses device allocations indirectly."]
+ pub const ZE_KERNEL_INDIRECT_ACCESS_FLAG_DEVICE: _ze_kernel_indirect_access_flags_t =
+ _ze_kernel_indirect_access_flags_t(2);
+}
+impl _ze_kernel_indirect_access_flags_t {
+ #[doc = "< Indicates that the kernel accesses shared allocations indirectly."]
+ pub const ZE_KERNEL_INDIRECT_ACCESS_FLAG_SHARED: _ze_kernel_indirect_access_flags_t =
+ _ze_kernel_indirect_access_flags_t(4);
+}
+impl _ze_kernel_indirect_access_flags_t {
+ pub const ZE_KERNEL_INDIRECT_ACCESS_FLAG_FORCE_UINT32: _ze_kernel_indirect_access_flags_t =
+ _ze_kernel_indirect_access_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_kernel_indirect_access_flags_t> for _ze_kernel_indirect_access_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_kernel_indirect_access_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_kernel_indirect_access_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_kernel_indirect_access_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_kernel_indirect_access_flags_t> for _ze_kernel_indirect_access_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_kernel_indirect_access_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_kernel_indirect_access_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_kernel_indirect_access_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Kernel indirect access flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_kernel_indirect_access_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Kernel indirect access flags"]
+pub use self::_ze_kernel_indirect_access_flags_t as ze_kernel_indirect_access_flags_t;
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Sets kernel indirect access flags."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application should specify which allocations will be indirectly"]
+ #[doc = " accessed by the kernel to allow driver to optimize which allocations"]
+ #[doc = " are made resident"]
+ #[doc = " - This function may **not** be called from simultaneous threads with the"]
+ #[doc = " same Kernel handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hKernel`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `0x7 < flags`"]
+ pub fn zeKernelSetIndirectAccess(
+ hKernel: ze_kernel_handle_t,
+ flags: ze_kernel_indirect_access_flags_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieve kernel indirect access flags."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - This function may be called from simultaneous threads with the same"]
+ #[doc = " Kernel handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hKernel`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pFlags`"]
+ pub fn zeKernelGetIndirectAccess(
+ hKernel: ze_kernel_handle_t,
+ pFlags: *mut ze_kernel_indirect_access_flags_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieve all declared kernel attributes (i.e. can be specified with"]
+ #[doc = " __attribute__ in runtime language)."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - This function may be called from simultaneous threads with the same"]
+ #[doc = " Kernel handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hKernel`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pSize`"]
+ pub fn zeKernelGetSourceAttributes(
+ hKernel: ze_kernel_handle_t,
+ pSize: *mut u32,
+ pString: *mut *mut ::std::os::raw::c_char,
+ ) -> ze_result_t;
+}
+impl _ze_cache_config_flags_t {
+ #[doc = "< Large SLM size"]
+ pub const ZE_CACHE_CONFIG_FLAG_LARGE_SLM: _ze_cache_config_flags_t =
+ _ze_cache_config_flags_t(1);
+}
+impl _ze_cache_config_flags_t {
+ #[doc = "< Large General Data size"]
+ pub const ZE_CACHE_CONFIG_FLAG_LARGE_DATA: _ze_cache_config_flags_t =
+ _ze_cache_config_flags_t(2);
+}
+impl _ze_cache_config_flags_t {
+ pub const ZE_CACHE_CONFIG_FLAG_FORCE_UINT32: _ze_cache_config_flags_t =
+ _ze_cache_config_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_cache_config_flags_t> for _ze_cache_config_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_cache_config_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_cache_config_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_cache_config_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_cache_config_flags_t> for _ze_cache_config_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_cache_config_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_cache_config_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_cache_config_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported Cache Config flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_cache_config_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported Cache Config flags"]
+pub use self::_ze_cache_config_flags_t as ze_cache_config_flags_t;
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Sets the preferred cache configuration for a kernel on the current"]
+ #[doc = " Host thread."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The implementation will maintain the cache configuration in"]
+ #[doc = " thread-local storage."]
+ #[doc = " - The cache configuration will be used when a"]
+ #[doc = " ::zeCommandListAppendLaunchKernel variant is called on the same Host"]
+ #[doc = " thread."]
+ #[doc = " - The application may call this function from simultaneous threads with"]
+ #[doc = " the same kernel handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hKernel`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `0x3 < flags`"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_FEATURE"]
+ pub fn zeKernelSetCacheConfig(
+ hKernel: ze_kernel_handle_t,
+ flags: ze_cache_config_flags_t,
+ ) -> ze_result_t;
+}
+#[doc = ""]
+#[doc = " @brief Kernel universal unique id (UUID)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_kernel_uuid_t {
+ #[doc = "< [out] opaque data representing a kernel UUID"]
+ pub kid: [u8; 16usize],
+ #[doc = "< [out] opaque data representing the kernel's module UUID"]
+ pub mid: [u8; 16usize],
+}
+#[test]
+fn bindgen_test_layout__ze_kernel_uuid_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_kernel_uuid_t>(),
+ 32usize,
+ concat!("Size of: ", stringify!(_ze_kernel_uuid_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_kernel_uuid_t>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(_ze_kernel_uuid_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_kernel_uuid_t>())).kid as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_uuid_t),
+ "::",
+ stringify!(kid)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_kernel_uuid_t>())).mid as *const _ as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_uuid_t),
+ "::",
+ stringify!(mid)
+ )
+ );
+}
+#[doc = ""]
+#[doc = " @brief Kernel properties"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_kernel_properties_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in,out][optional] pointer to extension-specific structure"]
+ pub pNext: *mut ::std::os::raw::c_void,
+ #[doc = "< [out] number of kernel arguments."]
+ pub numKernelArgs: u32,
+ #[doc = "< [out] required group size in the X dimension,"]
+ #[doc = "< or zero if there is no required group size"]
+ pub requiredGroupSizeX: u32,
+ #[doc = "< [out] required group size in the Y dimension,"]
+ #[doc = "< or zero if there is no required group size"]
+ pub requiredGroupSizeY: u32,
+ #[doc = "< [out] required group size in the Z dimension,"]
+ #[doc = "< or zero if there is no required group size"]
+ pub requiredGroupSizeZ: u32,
+ #[doc = "< [out] required number of subgroups per thread group,"]
+ #[doc = "< or zero if there is no required number of subgroups"]
+ pub requiredNumSubGroups: u32,
+ #[doc = "< [out] required subgroup size,"]
+ #[doc = "< or zero if there is no required subgroup size"]
+ pub requiredSubgroupSize: u32,
+ #[doc = "< [out] maximum subgroup size"]
+ pub maxSubgroupSize: u32,
+ #[doc = "< [out] maximum number of subgroups per thread group"]
+ pub maxNumSubgroups: u32,
+ #[doc = "< [out] local memory size used by each thread group"]
+ pub localMemSize: u32,
+ #[doc = "< [out] private memory size allocated by compiler used by each thread"]
+ pub privateMemSize: u32,
+ #[doc = "< [out] spill memory size allocated by compiler"]
+ pub spillMemSize: u32,
+ #[doc = "< [out] universal unique identifier."]
+ pub uuid: ze_kernel_uuid_t,
+}
+#[test]
+fn bindgen_test_layout__ze_kernel_properties_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_kernel_properties_t>(),
+ 96usize,
+ concat!("Size of: ", stringify!(_ze_kernel_properties_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_kernel_properties_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_kernel_properties_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_kernel_properties_t>())).stype as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_properties_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_kernel_properties_t>())).pNext as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_properties_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_kernel_properties_t>())).numKernelArgs as *const _ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_properties_t),
+ "::",
+ stringify!(numKernelArgs)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_kernel_properties_t>())).requiredGroupSizeX as *const _
+ as usize
+ },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_properties_t),
+ "::",
+ stringify!(requiredGroupSizeX)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_kernel_properties_t>())).requiredGroupSizeY as *const _
+ as usize
+ },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_properties_t),
+ "::",
+ stringify!(requiredGroupSizeY)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_kernel_properties_t>())).requiredGroupSizeZ as *const _
+ as usize
+ },
+ 28usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_properties_t),
+ "::",
+ stringify!(requiredGroupSizeZ)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_kernel_properties_t>())).requiredNumSubGroups as *const _
+ as usize
+ },
+ 32usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_properties_t),
+ "::",
+ stringify!(requiredNumSubGroups)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_kernel_properties_t>())).requiredSubgroupSize as *const _
+ as usize
+ },
+ 36usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_properties_t),
+ "::",
+ stringify!(requiredSubgroupSize)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_kernel_properties_t>())).maxSubgroupSize as *const _ as usize
+ },
+ 40usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_properties_t),
+ "::",
+ stringify!(maxSubgroupSize)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_kernel_properties_t>())).maxNumSubgroups as *const _ as usize
+ },
+ 44usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_properties_t),
+ "::",
+ stringify!(maxNumSubgroups)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_kernel_properties_t>())).localMemSize as *const _ as usize
+ },
+ 48usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_properties_t),
+ "::",
+ stringify!(localMemSize)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_kernel_properties_t>())).privateMemSize as *const _ as usize
+ },
+ 52usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_properties_t),
+ "::",
+ stringify!(privateMemSize)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<_ze_kernel_properties_t>())).spillMemSize as *const _ as usize
+ },
+ 56usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_properties_t),
+ "::",
+ stringify!(spillMemSize)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_kernel_properties_t>())).uuid as *const _ as usize },
+ 60usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_kernel_properties_t),
+ "::",
+ stringify!(uuid)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieve kernel properties."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hKernel`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pKernelProperties`"]
+ pub fn zeKernelGetProperties(
+ hKernel: ze_kernel_handle_t,
+ pKernelProperties: *mut ze_kernel_properties_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Retrieve kernel name from Kernel."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The caller can pass nullptr for pName when querying only for size."]
+ #[doc = " - The implementation will copy the kernel name into a buffer supplied by"]
+ #[doc = " the caller."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hKernel`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pSize`"]
+ pub fn zeKernelGetName(
+ hKernel: ze_kernel_handle_t,
+ pSize: *mut usize,
+ pName: *mut ::std::os::raw::c_char,
+ ) -> ze_result_t;
+}
+#[doc = ""]
+#[doc = " @brief Kernel dispatch group count."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_group_count_t {
+ #[doc = "< [in] number of thread groups in X dimension"]
+ pub groupCountX: u32,
+ #[doc = "< [in] number of thread groups in Y dimension"]
+ pub groupCountY: u32,
+ #[doc = "< [in] number of thread groups in Z dimension"]
+ pub groupCountZ: u32,
+}
+#[test]
+fn bindgen_test_layout__ze_group_count_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_group_count_t>(),
+ 12usize,
+ concat!("Size of: ", stringify!(_ze_group_count_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_group_count_t>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(_ze_group_count_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_group_count_t>())).groupCountX as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_group_count_t),
+ "::",
+ stringify!(groupCountX)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_group_count_t>())).groupCountY as *const _ as usize },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_group_count_t),
+ "::",
+ stringify!(groupCountY)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_group_count_t>())).groupCountZ as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_group_count_t),
+ "::",
+ stringify!(groupCountZ)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Launch kernel over one or more work groups."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the kernel and events are accessible by"]
+ #[doc = " the device on which the command list was created."]
+ #[doc = " - This may **only** be called for a command list created with command"]
+ #[doc = " queue group ordinal that supports compute."]
+ #[doc = " - The application must ensure the command list, kernel and events were"]
+ #[doc = " created on the same context."]
+ #[doc = " - This function may **not** be called from simultaneous threads with the"]
+ #[doc = " same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " + `nullptr == hKernel`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pLaunchFuncArgs`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `(nullptr == phWaitEvents) && (0 < numWaitEvents)`"]
+ pub fn zeCommandListAppendLaunchKernel(
+ hCommandList: ze_command_list_handle_t,
+ hKernel: ze_kernel_handle_t,
+ pLaunchFuncArgs: *const ze_group_count_t,
+ hSignalEvent: ze_event_handle_t,
+ numWaitEvents: u32,
+ phWaitEvents: *mut ze_event_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Launch kernel cooperatively over one or more work groups."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the kernel and events are accessible by"]
+ #[doc = " the device on which the command list was created."]
+ #[doc = " - This may **only** be called for a command list created with command"]
+ #[doc = " queue group ordinal that supports compute."]
+ #[doc = " - This may only be used for a command list that are submitted to command"]
+ #[doc = " queue with cooperative flag set."]
+ #[doc = " - The application must ensure the command list, kernel and events were"]
+ #[doc = " created on the same context."]
+ #[doc = " - This function may **not** be called from simultaneous threads with the"]
+ #[doc = " same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = " - Use ::zeKernelSuggestMaxCooperativeGroupCount to recommend max group"]
+ #[doc = " count for device for cooperative functions that device supports."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " + `nullptr == hKernel`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pLaunchFuncArgs`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `(nullptr == phWaitEvents) && (0 < numWaitEvents)`"]
+ pub fn zeCommandListAppendLaunchCooperativeKernel(
+ hCommandList: ze_command_list_handle_t,
+ hKernel: ze_kernel_handle_t,
+ pLaunchFuncArgs: *const ze_group_count_t,
+ hSignalEvent: ze_event_handle_t,
+ numWaitEvents: u32,
+ phWaitEvents: *mut ze_event_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Launch kernel over one or more work groups using indirect arguments."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the kernel and events are accessible by"]
+ #[doc = " the device on which the command list was created."]
+ #[doc = " - The application must ensure the launch arguments are visible to the"]
+ #[doc = " device on which the command list was created."]
+ #[doc = " - The implementation must not access the contents of the launch"]
+ #[doc = " arguments as they are free to be modified by either the Host or device"]
+ #[doc = " up until execution."]
+ #[doc = " - This may **only** be called for a command list created with command"]
+ #[doc = " queue group ordinal that supports compute."]
+ #[doc = " - The application must ensure the command list, kernel and events were"]
+ #[doc = " created, and the memory was allocated, on the same context."]
+ #[doc = " - This function may **not** be called from simultaneous threads with the"]
+ #[doc = " same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " + `nullptr == hKernel`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pLaunchArgumentsBuffer`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `(nullptr == phWaitEvents) && (0 < numWaitEvents)`"]
+ pub fn zeCommandListAppendLaunchKernelIndirect(
+ hCommandList: ze_command_list_handle_t,
+ hKernel: ze_kernel_handle_t,
+ pLaunchArgumentsBuffer: *const ze_group_count_t,
+ hSignalEvent: ze_event_handle_t,
+ numWaitEvents: u32,
+ phWaitEvents: *mut ze_event_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Launch multiple kernels over one or more work groups using an array of"]
+ #[doc = " indirect arguments."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the kernel and events are accessible by"]
+ #[doc = " the device on which the command list was created."]
+ #[doc = " - The application must ensure the array of launch arguments and count"]
+ #[doc = " buffer are visible to the device on which the command list was"]
+ #[doc = " created."]
+ #[doc = " - The implementation must not access the contents of the array of launch"]
+ #[doc = " arguments or count buffer as they are free to be modified by either"]
+ #[doc = " the Host or device up until execution."]
+ #[doc = " - This may **only** be called for a command list created with command"]
+ #[doc = " queue group ordinal that supports compute."]
+ #[doc = " - The application must enusre the command list, kernel and events were"]
+ #[doc = " created, and the memory was allocated, on the same context."]
+ #[doc = " - This function may **not** be called from simultaneous threads with the"]
+ #[doc = " same command list handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hCommandList`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == phKernels`"]
+ #[doc = " + `nullptr == pCountBuffer`"]
+ #[doc = " + `nullptr == pLaunchArgumentsBuffer`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_SIZE"]
+ #[doc = " + `(nullptr == phWaitEvents) && (0 < numWaitEvents)`"]
+ pub fn zeCommandListAppendLaunchMultipleKernelsIndirect(
+ hCommandList: ze_command_list_handle_t,
+ numKernels: u32,
+ phKernels: *mut ze_kernel_handle_t,
+ pCountBuffer: *const u32,
+ pLaunchArgumentsBuffer: *const ze_group_count_t,
+ hSignalEvent: ze_event_handle_t,
+ numWaitEvents: u32,
+ phWaitEvents: *mut ze_event_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Makes memory resident for the device."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the memory is resident before being"]
+ #[doc = " referenced by the device"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == ptr`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ pub fn zeContextMakeMemoryResident(
+ hContext: ze_context_handle_t,
+ hDevice: ze_device_handle_t,
+ ptr: *mut ::std::os::raw::c_void,
+ size: usize,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Allows memory to be evicted from the device."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the device is not currently referencing"]
+ #[doc = " the memory before it is evicted"]
+ #[doc = " - The application may free the memory without evicting; the memory is"]
+ #[doc = " implicitly evicted when freed."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == ptr`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ pub fn zeContextEvictMemory(
+ hContext: ze_context_handle_t,
+ hDevice: ze_device_handle_t,
+ ptr: *mut ::std::os::raw::c_void,
+ size: usize,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Makes image resident for the device."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the image is resident before being"]
+ #[doc = " referenced by the device"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " + `nullptr == hImage`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ pub fn zeContextMakeImageResident(
+ hContext: ze_context_handle_t,
+ hDevice: ze_device_handle_t,
+ hImage: ze_image_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Allows image to be evicted from the device."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the device is not currently referencing"]
+ #[doc = " the image before it is evicted"]
+ #[doc = " - The application may destroy the image without evicting; the image is"]
+ #[doc = " implicitly evicted when destroyed."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " + `nullptr == hImage`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ pub fn zeContextEvictImage(
+ hContext: ze_context_handle_t,
+ hDevice: ze_device_handle_t,
+ hImage: ze_image_handle_t,
+ ) -> ze_result_t;
+}
+impl _ze_sampler_address_mode_t {
+ #[doc = "< No coordinate modifications for out-of-bounds image access."]
+ pub const ZE_SAMPLER_ADDRESS_MODE_NONE: _ze_sampler_address_mode_t =
+ _ze_sampler_address_mode_t(0);
+}
+impl _ze_sampler_address_mode_t {
+ #[doc = "< Out-of-bounds coordinates are wrapped back around."]
+ pub const ZE_SAMPLER_ADDRESS_MODE_REPEAT: _ze_sampler_address_mode_t =
+ _ze_sampler_address_mode_t(1);
+}
+impl _ze_sampler_address_mode_t {
+ #[doc = "< Out-of-bounds coordinates are clamped to edge."]
+ pub const ZE_SAMPLER_ADDRESS_MODE_CLAMP: _ze_sampler_address_mode_t =
+ _ze_sampler_address_mode_t(2);
+}
+impl _ze_sampler_address_mode_t {
+ #[doc = "< Out-of-bounds coordinates are clamped to border color which is (0.0f,"]
+ #[doc = "< 0.0f, 0.0f, 0.0f) if image format swizzle contains alpha, otherwise"]
+ #[doc = "< (0.0f, 0.0f, 0.0f, 1.0f)."]
+ pub const ZE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER: _ze_sampler_address_mode_t =
+ _ze_sampler_address_mode_t(3);
+}
+impl _ze_sampler_address_mode_t {
+ #[doc = "< Out-of-bounds coordinates are mirrored starting from edge."]
+ pub const ZE_SAMPLER_ADDRESS_MODE_MIRROR: _ze_sampler_address_mode_t =
+ _ze_sampler_address_mode_t(4);
+}
+impl _ze_sampler_address_mode_t {
+ pub const ZE_SAMPLER_ADDRESS_MODE_FORCE_UINT32: _ze_sampler_address_mode_t =
+ _ze_sampler_address_mode_t(2147483647);
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Sampler addressing modes"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_sampler_address_mode_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Sampler addressing modes"]
+pub use self::_ze_sampler_address_mode_t as ze_sampler_address_mode_t;
+impl _ze_sampler_filter_mode_t {
+ #[doc = "< No coordinate modifications for out of bounds image access."]
+ pub const ZE_SAMPLER_FILTER_MODE_NEAREST: _ze_sampler_filter_mode_t =
+ _ze_sampler_filter_mode_t(0);
+}
+impl _ze_sampler_filter_mode_t {
+ #[doc = "< Out-of-bounds coordinates are wrapped back around."]
+ pub const ZE_SAMPLER_FILTER_MODE_LINEAR: _ze_sampler_filter_mode_t =
+ _ze_sampler_filter_mode_t(1);
+}
+impl _ze_sampler_filter_mode_t {
+ pub const ZE_SAMPLER_FILTER_MODE_FORCE_UINT32: _ze_sampler_filter_mode_t =
+ _ze_sampler_filter_mode_t(2147483647);
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Sampler filtering modes"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_sampler_filter_mode_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Sampler filtering modes"]
+pub use self::_ze_sampler_filter_mode_t as ze_sampler_filter_mode_t;
+#[doc = ""]
+#[doc = " @brief Sampler descriptor"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_sampler_desc_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in][optional] pointer to extension-specific structure"]
+ pub pNext: *const ::std::os::raw::c_void,
+ #[doc = "< [in] Sampler addressing mode to determine how out-of-bounds"]
+ #[doc = "< coordinates are handled."]
+ pub addressMode: ze_sampler_address_mode_t,
+ #[doc = "< [in] Sampler filter mode to determine how samples are filtered."]
+ pub filterMode: ze_sampler_filter_mode_t,
+ #[doc = "< [in] Are coordinates normalized [0, 1] or not."]
+ pub isNormalized: ze_bool_t,
+}
+#[test]
+fn bindgen_test_layout__ze_sampler_desc_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_sampler_desc_t>(),
+ 32usize,
+ concat!("Size of: ", stringify!(_ze_sampler_desc_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_sampler_desc_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_sampler_desc_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_sampler_desc_t>())).stype as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_sampler_desc_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_sampler_desc_t>())).pNext as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_sampler_desc_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_sampler_desc_t>())).addressMode as *const _ as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_sampler_desc_t),
+ "::",
+ stringify!(addressMode)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_sampler_desc_t>())).filterMode as *const _ as usize },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_sampler_desc_t),
+ "::",
+ stringify!(filterMode)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_sampler_desc_t>())).isNormalized as *const _ as usize },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_sampler_desc_t),
+ "::",
+ stringify!(isNormalized)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Creates sampler on the context."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must only use the sampler for the device, or its"]
+ #[doc = " sub-devices, which was provided during creation."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == desc`"]
+ #[doc = " + `nullptr == phSampler`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `::ZE_SAMPLER_ADDRESS_MODE_MIRROR < desc->addressMode`"]
+ #[doc = " + `::ZE_SAMPLER_FILTER_MODE_LINEAR < desc->filterMode`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ pub fn zeSamplerCreate(
+ hContext: ze_context_handle_t,
+ hDevice: ze_device_handle_t,
+ desc: *const ze_sampler_desc_t,
+ phSampler: *mut ze_sampler_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Destroys sampler object"]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the device is not currently referencing"]
+ #[doc = " the sampler before it is deleted."]
+ #[doc = " - The implementation of this function may immediately free all Host and"]
+ #[doc = " Device allocations associated with this sampler."]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same sampler handle."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hSampler`"]
+ #[doc = " - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE"]
+ pub fn zeSamplerDestroy(hSampler: ze_sampler_handle_t) -> ze_result_t;
+}
+impl _ze_memory_access_attribute_t {
+ #[doc = "< Indicates the memory page is inaccessible."]
+ pub const ZE_MEMORY_ACCESS_ATTRIBUTE_NONE: _ze_memory_access_attribute_t =
+ _ze_memory_access_attribute_t(0);
+}
+impl _ze_memory_access_attribute_t {
+ #[doc = "< Indicates the memory page supports read write access."]
+ pub const ZE_MEMORY_ACCESS_ATTRIBUTE_READWRITE: _ze_memory_access_attribute_t =
+ _ze_memory_access_attribute_t(1);
+}
+impl _ze_memory_access_attribute_t {
+ #[doc = "< Indicates the memory page supports read-only access."]
+ pub const ZE_MEMORY_ACCESS_ATTRIBUTE_READONLY: _ze_memory_access_attribute_t =
+ _ze_memory_access_attribute_t(2);
+}
+impl _ze_memory_access_attribute_t {
+ pub const ZE_MEMORY_ACCESS_ATTRIBUTE_FORCE_UINT32: _ze_memory_access_attribute_t =
+ _ze_memory_access_attribute_t(2147483647);
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Virtual memory page access attributes"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_memory_access_attribute_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Virtual memory page access attributes"]
+pub use self::_ze_memory_access_attribute_t as ze_memory_access_attribute_t;
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Reserves pages in virtual address space."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must only use the memory allocation on the context for"]
+ #[doc = " which it was created."]
+ #[doc = " - The starting address and size must be page aligned. See"]
+ #[doc = " ::zeVirtualMemQueryPageSize."]
+ #[doc = " - If pStart is not null then implementation will attempt to reserve"]
+ #[doc = " starting from that address. If not available then will find another"]
+ #[doc = " suitable starting address."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The access attributes will default to none to indicate reservation is"]
+ #[doc = " inaccessible."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pStart`"]
+ #[doc = " + `nullptr == pptr`"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE"]
+ #[doc = " + `0 == size`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ pub fn zeVirtualMemReserve(
+ hContext: ze_context_handle_t,
+ pStart: *const ::std::os::raw::c_void,
+ size: usize,
+ pptr: *mut *mut ::std::os::raw::c_void,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Free pages in a reserved virtual address range."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - Any existing virtual mappings for the range will be unmapped."]
+ #[doc = " - Physical allocations objects that were mapped to this range will not"]
+ #[doc = " be destroyed. These need to be destroyed explicitly."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == ptr`"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE"]
+ #[doc = " + `0 == size`"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT"]
+ pub fn zeVirtualMemFree(
+ hContext: ze_context_handle_t,
+ ptr: *const ::std::os::raw::c_void,
+ size: usize,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Queries page size to use for aligning virtual memory reservations and"]
+ #[doc = " physical memory allocations."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == pagesize`"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE"]
+ #[doc = " + `0 == size`"]
+ pub fn zeVirtualMemQueryPageSize(
+ hContext: ze_context_handle_t,
+ hDevice: ze_device_handle_t,
+ size: usize,
+ pagesize: *mut usize,
+ ) -> ze_result_t;
+}
+impl _ze_physical_mem_flags_t {
+ #[doc = "< reserved for future use."]
+ pub const ZE_PHYSICAL_MEM_FLAG_TBD: _ze_physical_mem_flags_t = _ze_physical_mem_flags_t(1);
+}
+impl _ze_physical_mem_flags_t {
+ pub const ZE_PHYSICAL_MEM_FLAG_FORCE_UINT32: _ze_physical_mem_flags_t =
+ _ze_physical_mem_flags_t(2147483647);
+}
+impl ::std::ops::BitOr<_ze_physical_mem_flags_t> for _ze_physical_mem_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ _ze_physical_mem_flags_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for _ze_physical_mem_flags_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: _ze_physical_mem_flags_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<_ze_physical_mem_flags_t> for _ze_physical_mem_flags_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ _ze_physical_mem_flags_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for _ze_physical_mem_flags_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: _ze_physical_mem_flags_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[doc = ""]
+#[doc = " @brief Supported physical memory creation flags"]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct _ze_physical_mem_flags_t(pub u32);
+#[doc = ""]
+#[doc = " @brief Supported physical memory creation flags"]
+pub use self::_ze_physical_mem_flags_t as ze_physical_mem_flags_t;
+#[doc = ""]
+#[doc = " @brief Physical memory descriptor"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct _ze_physical_mem_desc_t {
+ #[doc = "< [in] type of this structure"]
+ pub stype: ze_structure_type_t,
+ #[doc = "< [in][optional] pointer to extension-specific structure"]
+ pub pNext: *const ::std::os::raw::c_void,
+ #[doc = "< [in] creation flags."]
+ #[doc = "< must be 0 (default) or a valid combination of ::ze_physical_mem_flags_t."]
+ pub flags: ze_physical_mem_flags_t,
+ #[doc = "< [in] size in bytes to reserve; must be page aligned."]
+ pub size: usize,
+}
+#[test]
+fn bindgen_test_layout__ze_physical_mem_desc_t() {
+ assert_eq!(
+ ::std::mem::size_of::<_ze_physical_mem_desc_t>(),
+ 32usize,
+ concat!("Size of: ", stringify!(_ze_physical_mem_desc_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_ze_physical_mem_desc_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_ze_physical_mem_desc_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_physical_mem_desc_t>())).stype as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_physical_mem_desc_t),
+ "::",
+ stringify!(stype)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_physical_mem_desc_t>())).pNext as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_physical_mem_desc_t),
+ "::",
+ stringify!(pNext)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_physical_mem_desc_t>())).flags as *const _ as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_physical_mem_desc_t),
+ "::",
+ stringify!(flags)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<_ze_physical_mem_desc_t>())).size as *const _ as usize },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(_ze_physical_mem_desc_t),
+ "::",
+ stringify!(size)
+ )
+ );
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Creates a physical memory object for the context."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must only use the physical memory object on the"]
+ #[doc = " context for which it was created."]
+ #[doc = " - The size must be page aligned. See ::zeVirtualMemQueryPageSize."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " + `nullptr == hDevice`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == desc`"]
+ #[doc = " + `nullptr == phPhysicalMemory`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `0x1 < desc->flags`"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE"]
+ #[doc = " + `0 == desc->size`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT"]
+ pub fn zePhysicalMemCreate(
+ hContext: ze_context_handle_t,
+ hDevice: ze_device_handle_t,
+ desc: *mut ze_physical_mem_desc_t,
+ phPhysicalMemory: *mut ze_physical_mem_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Destroys a physical memory object."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The application must ensure the device is not currently referencing"]
+ #[doc = " the physical memory object before it is deleted"]
+ #[doc = " - The application must **not** call this function from simultaneous"]
+ #[doc = " threads with the same physical memory handle."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " + `nullptr == hPhysicalMemory`"]
+ #[doc = " - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE"]
+ pub fn zePhysicalMemDestroy(
+ hContext: ze_context_handle_t,
+ hPhysicalMemory: ze_physical_mem_handle_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Maps pages in virtual address space to pages from physical memory"]
+ #[doc = " object."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The virtual address range must have been reserved using"]
+ #[doc = " ::zeVirtualMemReserve."]
+ #[doc = " - The application must only use the mapped memory allocation on the"]
+ #[doc = " context for which it was created."]
+ #[doc = " - The virtual start address and size must be page aligned. See"]
+ #[doc = " ::zeVirtualMemQueryPageSize."]
+ #[doc = " - The application should use, for the starting address and size, the"]
+ #[doc = " same size alignment used for the physical allocation."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " + `nullptr == hPhysicalMemory`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == ptr`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `::ZE_MEMORY_ACCESS_ATTRIBUTE_READONLY < access`"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE"]
+ #[doc = " + `0 == size`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT"]
+ pub fn zeVirtualMemMap(
+ hContext: ze_context_handle_t,
+ ptr: *const ::std::os::raw::c_void,
+ size: usize,
+ hPhysicalMemory: ze_physical_mem_handle_t,
+ offset: usize,
+ access: ze_memory_access_attribute_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Unmaps pages in virtual address space from pages from a physical"]
+ #[doc = " memory object."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - The page access attributes for virtual address range will revert back"]
+ #[doc = " to none."]
+ #[doc = " - The application may call this function from simultaneous threads."]
+ #[doc = " - The implementation of this function must be thread-safe."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == ptr`"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT - \"Address must be page aligned\""]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE"]
+ #[doc = " + `0 == size`"]
+ #[doc = " + Size must be page aligned"]
+ pub fn zeVirtualMemUnmap(
+ hContext: ze_context_handle_t,
+ ptr: *const ::std::os::raw::c_void,
+ size: usize,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Set memory access attributes for a virtual address range."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - This function may be called from simultaneous threads with the same"]
+ #[doc = " function handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == ptr`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_ENUMERATION"]
+ #[doc = " + `::ZE_MEMORY_ACCESS_ATTRIBUTE_READONLY < access`"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT - \"Address must be page aligned\""]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE"]
+ #[doc = " + `0 == size`"]
+ #[doc = " + Size must be page aligned"]
+ pub fn zeVirtualMemSetAccessAttribute(
+ hContext: ze_context_handle_t,
+ ptr: *const ::std::os::raw::c_void,
+ size: usize,
+ access: ze_memory_access_attribute_t,
+ ) -> ze_result_t;
+}
+extern "C" {
+ #[doc = ""]
+ #[doc = " @brief Get memory access attribute for a virtual address range."]
+ #[doc = ""]
+ #[doc = " @details"]
+ #[doc = " - If size and outSize are equal then the pages in the specified virtual"]
+ #[doc = " address range have the same access attributes."]
+ #[doc = " - This function may be called from simultaneous threads with the same"]
+ #[doc = " function handle."]
+ #[doc = " - The implementation of this function should be lock-free."]
+ #[doc = ""]
+ #[doc = " @returns"]
+ #[doc = " - ::ZE_RESULT_SUCCESS"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNINITIALIZED"]
+ #[doc = " - ::ZE_RESULT_ERROR_DEVICE_LOST"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE"]
+ #[doc = " + `nullptr == hContext`"]
+ #[doc = " - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER"]
+ #[doc = " + `nullptr == ptr`"]
+ #[doc = " + `nullptr == access`"]
+ #[doc = " + `nullptr == outSize`"]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT - \"Address must be page aligned\""]
+ #[doc = " - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE"]
+ #[doc = " + `0 == size`"]
+ #[doc = " + Size must be page aligned"]
+ pub fn zeVirtualMemGetAccessAttribute(
+ hContext: ze_context_handle_t,
+ ptr: *const ::std::os::raw::c_void,
+ size: usize,
+ access: *mut ze_memory_access_attribute_t,
+ outSize: *mut usize,
+ ) -> ze_result_t;
+}
diff --git a/level_zero-sys/src/ze_loader.lib b/level_zero-sys/src/ze_loader.lib
new file mode 100644
index 0000000..661240c
--- /dev/null
+++ b/level_zero-sys/src/ze_loader.lib
Binary files differ
diff --git a/level_zero/Cargo.toml b/level_zero/Cargo.toml
new file mode 100644
index 0000000..851159d
--- /dev/null
+++ b/level_zero/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "level_zero"
+version = "0.1.0"
+authors = ["Andrzej Janik <[email protected]>"]
+edition = "2018"
+
+[lib]
+
+[dependencies]
+level_zero-sys = { path = "../level_zero-sys" }
+
+[dependencies.ocl-core]
+version = "0.11"
+features = ["opencl_version_1_2", "opencl_version_2_0", "opencl_version_2_1"] \ No newline at end of file
diff --git a/level_zero/README b/level_zero/README
new file mode 100644
index 0000000..b9785bf
--- /dev/null
+++ b/level_zero/README
@@ -0,0 +1 @@
+More ergonomic bindings for oneAPI Level Zero
diff --git a/level_zero/src/lib.rs b/level_zero/src/lib.rs
new file mode 100644
index 0000000..bdc25a8
--- /dev/null
+++ b/level_zero/src/lib.rs
@@ -0,0 +1,4 @@
+pub use level_zero_sys as sys;
+
+pub mod ze;
+pub use ze::*; \ No newline at end of file
diff --git a/level_zero/src/ze.rs b/level_zero/src/ze.rs
new file mode 100644
index 0000000..c56321a
--- /dev/null
+++ b/level_zero/src/ze.rs
@@ -0,0 +1,909 @@
+use crate::sys;
+use std::{
+ ffi::{c_void, CStr, CString},
+ fmt::Debug,
+ marker::PhantomData,
+ mem, ptr,
+};
+
+macro_rules! check {
+ ($expr:expr) => {
+ #[allow(unused_unsafe)]
+ {
+ let err = unsafe { $expr };
+ if err != crate::sys::ze_result_t::ZE_RESULT_SUCCESS {
+ return Result::Err(err);
+ }
+ }
+ };
+}
+
+macro_rules! check_panic {
+ ($expr:expr) => {
+ let err = unsafe { $expr };
+ if err != crate::sys::ze_result_t::ZE_RESULT_SUCCESS {
+ panic!(err);
+ }
+ };
+}
+
+pub type Result<T> = std::result::Result<T, sys::ze_result_t>;
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct Error(pub sys::ze_result_t);
+
+pub fn init() -> Result<()> {
+ match unsafe { sys::zeInit(sys::ze_init_flags_t::ZE_INIT_FLAG_GPU_ONLY) } {
+ sys::ze_result_t::ZE_RESULT_SUCCESS => Ok(()),
+ e => Err(e),
+ }
+}
+
+#[repr(transparent)]
+pub struct Driver(sys::ze_driver_handle_t);
+
+unsafe impl Send for Driver {}
+unsafe impl Sync for Driver {}
+
+impl Driver {
+ pub unsafe fn as_ffi(&self) -> sys::ze_driver_handle_t {
+ self.0
+ }
+ pub unsafe fn from_ffi(x: sys::ze_driver_handle_t) -> Self {
+ Self(x)
+ }
+
+ pub fn get() -> Result<Vec<Self>> {
+ let mut len = 0;
+ let mut temp = ptr::null_mut();
+ check!(sys::zeDriverGet(&mut len, &mut temp));
+ let mut result = (0..len)
+ .map(|_| Driver(ptr::null_mut()))
+ .collect::<Vec<_>>();
+ check!(sys::zeDriverGet(&mut len, result.as_mut_ptr() as *mut _));
+ Ok(result)
+ }
+
+ pub fn devices(&self) -> Result<Vec<Device>> {
+ let mut len = 0;
+ let mut temp = ptr::null_mut();
+ check!(sys::zeDeviceGet(self.0, &mut len, &mut temp));
+ let mut result = (0..len)
+ .map(|_| Device(ptr::null_mut()))
+ .collect::<Vec<_>>();
+ check!(sys::zeDeviceGet(
+ self.0,
+ &mut len,
+ result.as_mut_ptr() as *mut _
+ ));
+ if (len as usize) < result.len() {
+ result.truncate(len as usize);
+ }
+ Ok(result)
+ }
+}
+
+#[repr(transparent)]
+pub struct Device(sys::ze_device_handle_t);
+
+impl Device {
+ pub unsafe fn as_ffi(&self) -> sys::ze_device_handle_t {
+ self.0
+ }
+ pub unsafe fn from_ffi(x: sys::ze_device_handle_t) -> Self {
+ Self(x)
+ }
+
+ pub fn get_properties(&self) -> Result<Box<sys::ze_device_properties_t>> {
+ let mut props = Box::new(unsafe { mem::zeroed::<sys::ze_device_properties_t>() });
+ check! { sys::zeDeviceGetProperties(self.0, props.as_mut()) };
+ Ok(props)
+ }
+
+ pub fn get_image_properties(&self) -> Result<Box<sys::ze_device_image_properties_t>> {
+ let mut props = Box::new(unsafe { mem::zeroed::<sys::ze_device_image_properties_t>() });
+ check! { sys::zeDeviceGetImageProperties(self.0, props.as_mut()) };
+ Ok(props)
+ }
+
+ pub fn get_memory_properties(&self) -> Result<Vec<sys::ze_device_memory_properties_t>> {
+ let mut count = 0u32;
+ check! { sys::zeDeviceGetMemoryProperties(self.0, &mut count, ptr::null_mut()) };
+ if count == 0 {
+ return Ok(Vec::new());
+ }
+ let mut props =
+ vec![unsafe { mem::zeroed::<sys::ze_device_memory_properties_t>() }; count as usize];
+ check! { sys::zeDeviceGetMemoryProperties(self.0, &mut count, props.as_mut_ptr()) };
+ Ok(props)
+ }
+
+ pub fn get_compute_properties(&self) -> Result<Box<sys::ze_device_compute_properties_t>> {
+ let mut props = Box::new(unsafe { mem::zeroed::<sys::ze_device_compute_properties_t>() });
+ check! { sys::zeDeviceGetComputeProperties(self.0, props.as_mut()) };
+ Ok(props)
+ }
+
+ pub unsafe fn mem_alloc_device(
+ &mut self,
+ ctx: &mut Context,
+ size: usize,
+ alignment: usize,
+ ) -> Result<*mut c_void> {
+ let descr = sys::ze_device_mem_alloc_desc_t {
+ stype: sys::ze_structure_type_t::ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC,
+ pNext: ptr::null(),
+ flags: sys::ze_device_mem_alloc_flags_t(0),
+ ordinal: 0,
+ };
+ let mut result = ptr::null_mut();
+ // TODO: check current context for the device
+ check! {
+ sys::zeMemAllocDevice(
+ ctx.0,
+ &descr,
+ size,
+ alignment,
+ self.0,
+ &mut result,
+ )
+ };
+ Ok(result)
+ }
+}
+
+#[repr(transparent)]
+pub struct Context(sys::ze_context_handle_t);
+
+impl Context {
+ pub unsafe fn as_ffi(&self) -> sys::ze_context_handle_t {
+ self.0
+ }
+ pub unsafe fn from_ffi(x: sys::ze_context_handle_t) -> Self {
+ Self(x)
+ }
+
+ pub fn new(drv: &Driver) -> Result<Self> {
+ let ctx_desc = sys::ze_context_desc_t {
+ stype: sys::ze_structure_type_t::ZE_STRUCTURE_TYPE_CONTEXT_DESC,
+ pNext: ptr::null(),
+ flags: sys::ze_context_flags_t(0),
+ };
+ let mut result = ptr::null_mut();
+ check!(sys::zeContextCreate(drv.0, &ctx_desc, &mut result));
+ Ok(Context(result))
+ }
+
+ pub unsafe fn mem_free(&mut self, ptr: *mut c_void) -> Result<()> {
+ check! {
+ sys::zeMemFree(
+ self.0,
+ ptr,
+ )
+ };
+ Ok(())
+ }
+}
+
+impl Drop for Context {
+ #[allow(unused_must_use)]
+ fn drop(&mut self) {
+ check_panic! { sys::zeContextDestroy(self.0) };
+ }
+}
+
+#[repr(transparent)]
+pub struct CommandQueue(sys::ze_command_queue_handle_t);
+
+impl CommandQueue {
+ pub unsafe fn as_ffi(&self) -> sys::ze_command_queue_handle_t {
+ self.0
+ }
+ pub unsafe fn from_ffi(x: sys::ze_command_queue_handle_t) -> Self {
+ Self(x)
+ }
+
+ pub fn new(ctx: &mut Context, d: &Device) -> Result<Self> {
+ let que_desc = sys::ze_command_queue_desc_t {
+ stype: sys::ze_structure_type_t::ZE_STRUCTURE_TYPE_COMMAND_QUEUE_DESC,
+ pNext: ptr::null(),
+ ordinal: 0,
+ index: 0,
+ flags: sys::ze_command_queue_flags_t(0),
+ mode: sys::ze_command_queue_mode_t::ZE_COMMAND_QUEUE_MODE_DEFAULT,
+ priority: sys::ze_command_queue_priority_t::ZE_COMMAND_QUEUE_PRIORITY_NORMAL,
+ };
+ let mut result = ptr::null_mut();
+ check!(sys::zeCommandQueueCreate(
+ ctx.0,
+ d.0,
+ &que_desc,
+ &mut result
+ ));
+ Ok(CommandQueue(result))
+ }
+
+ pub fn execute<'a>(&'a self, cmd: CommandList) -> Result<FenceGuard<'a>> {
+ check!(sys::zeCommandListClose(cmd.0));
+ let result = FenceGuard::new(self, cmd.0)?;
+ let mut raw_cmd = cmd.0;
+ mem::forget(cmd);
+ check!(sys::zeCommandQueueExecuteCommandLists(
+ self.0,
+ 1,
+ &mut raw_cmd,
+ result.0
+ ));
+ Ok(result)
+ }
+}
+
+impl Drop for CommandQueue {
+ #[allow(unused_must_use)]
+ fn drop(&mut self) {
+ check_panic! { sys::zeCommandQueueDestroy(self.0) };
+ }
+}
+
+pub struct Module(sys::ze_module_handle_t);
+
+impl Module {
+ // HACK ALERT
+ // We use OpenCL for now to do SPIR-V linking, because Level0
+ // does not allow linking. Don't let presence of zeModuleDynamicLink fool
+ // you, it's not currently possible to create non-compiled modules.
+ // zeModuleCreate always compiles (builds and links).
+ pub fn build_link_spirv<'a>(
+ ctx: &mut Context,
+ d: &Device,
+ binaries: &[&'a [u8]],
+ opts: Option<&CStr>,
+ ) -> (Result<Self>, Option<BuildLog>) {
+ let ocl_program = match Self::build_link_spirv_impl(binaries, opts) {
+ Err(_) => {
+ return (
+ Err(sys::ze_result_t::ZE_RESULT_ERROR_MODULE_LINK_FAILURE),
+ None,
+ )
+ }
+ Ok(prog) => prog,
+ };
+ match ocl_core::get_program_info(&ocl_program, ocl_core::ProgramInfo::Binaries) {
+ Ok(ocl_core::ProgramInfoResult::Binaries(binaries)) => {
+ let (module, build_log) = Self::build_native(ctx, d, &binaries[0]);
+ (module, Some(build_log))
+ }
+ _ => return (Err(sys::ze_result_t::ZE_RESULT_ERROR_UNKNOWN), None),
+ }
+ }
+
+ fn build_link_spirv_impl<'a>(
+ binaries: &[&'a [u8]],
+ opts: Option<&CStr>,
+ ) -> ocl_core::Result<ocl_core::Program> {
+ let platforms = ocl_core::get_platform_ids()?;
+ let (platform, device) = platforms
+ .iter()
+ .find_map(|plat| {
+ let devices =
+ ocl_core::get_device_ids(plat, Some(ocl_core::DeviceType::GPU), None).ok()?;
+ for dev in devices {
+ let vendor =
+ ocl_core::get_device_info(dev, ocl_core::DeviceInfo::VendorId).ok()?;
+ if let ocl_core::DeviceInfoResult::VendorId(0x8086) = vendor {
+ let dev_type =
+ ocl_core::get_device_info(dev, ocl_core::DeviceInfo::Type).ok()?;
+ if let ocl_core::DeviceInfoResult::Type(ocl_core::DeviceType::GPU) =
+ dev_type
+ {
+ return Some((plat.clone(), dev));
+ }
+ }
+ }
+ None
+ })
+ .ok_or("")?;
+ let ctx_props = ocl_core::ContextProperties::new().platform(platform);
+ let ocl_ctx = ocl_core::create_context_from_type::<ocl_core::DeviceId>(
+ Some(&ctx_props),
+ ocl_core::DeviceType::GPU,
+ None,
+ None,
+ )?;
+ let mut programs = Vec::with_capacity(binaries.len());
+ for binary in binaries {
+ programs.push(ocl_core::create_program_with_il(&ocl_ctx, binary, None)?);
+ }
+ let options = match opts {
+ Some(o) => o.to_owned(),
+ None => CString::default(),
+ };
+ for program in programs.iter() {
+ ocl_core::compile_program(
+ program,
+ Some(&[device]),
+ &options,
+ &[],
+ &[],
+ None,
+ None,
+ None,
+ )?;
+ }
+ ocl_core::link_program::<ocl_core::DeviceId, _>(
+ &ocl_ctx,
+ Some(&[device]),
+ &options,
+ &programs.iter().collect::<Vec<_>>(),
+ None,
+ None,
+ None,
+ )
+ }
+
+ pub fn build_spirv(
+ ctx: &mut Context,
+ d: &Device,
+ bin: &[u8],
+ opts: Option<&CStr>,
+ ) -> (Result<Self>, BuildLog) {
+ Module::new(ctx, true, d, bin, opts)
+ }
+
+ pub fn build_native(ctx: &mut Context, d: &Device, bin: &[u8]) -> (Result<Self>, BuildLog) {
+ Module::new(ctx, false, d, bin, None)
+ }
+
+ fn new(
+ ctx: &mut Context,
+ spirv: bool,
+ d: &Device,
+ bin: &[u8],
+ opts: Option<&CStr>,
+ ) -> (Result<Self>, BuildLog) {
+ let desc = sys::ze_module_desc_t {
+ stype: sys::ze_structure_type_t::ZE_STRUCTURE_TYPE_MODULE_DESC,
+ pNext: ptr::null(),
+ format: if spirv {
+ sys::ze_module_format_t::ZE_MODULE_FORMAT_IL_SPIRV
+ } else {
+ sys::ze_module_format_t::ZE_MODULE_FORMAT_NATIVE
+ },
+ inputSize: bin.len(),
+ pInputModule: bin.as_ptr(),
+ pBuildFlags: opts.map(|s| s.as_ptr() as *const _).unwrap_or(ptr::null()),
+ pConstants: ptr::null(),
+ };
+ let mut result: sys::ze_module_handle_t = ptr::null_mut();
+ let mut log_handle = ptr::null_mut();
+ let err = unsafe { sys::zeModuleCreate(ctx.0, d.0, &desc, &mut result, &mut log_handle) };
+ let log = BuildLog(log_handle);
+ if err != crate::sys::ze_result_t::ZE_RESULT_SUCCESS {
+ (Result::Err(err), log)
+ } else {
+ (Ok(Module(result)), log)
+ }
+ }
+}
+
+impl Drop for Module {
+ #[allow(unused_must_use)]
+ fn drop(&mut self) {
+ check_panic! { sys::zeModuleDestroy(self.0) };
+ }
+}
+
+pub struct BuildLog(sys::ze_module_build_log_handle_t);
+
+impl BuildLog {
+ pub unsafe fn as_ffi(&self) -> sys::ze_module_build_log_handle_t {
+ self.0
+ }
+ pub unsafe fn from_ffi(x: sys::ze_module_build_log_handle_t) -> Self {
+ Self(x)
+ }
+
+ pub fn get_cstring(&self) -> Result<CString> {
+ let mut size = 0;
+ check! { sys::zeModuleBuildLogGetString(self.0, &mut size, ptr::null_mut()) };
+ let mut str_vec = vec![0u8; size];
+ check! { sys::zeModuleBuildLogGetString(self.0, &mut size, str_vec.as_mut_ptr() as *mut i8) };
+ str_vec.pop();
+ Ok(CString::new(str_vec).map_err(|_| sys::ze_result_t::ZE_RESULT_ERROR_UNKNOWN)?)
+ }
+}
+
+impl Drop for BuildLog {
+ fn drop(&mut self) {
+ check_panic!(sys::zeModuleBuildLogDestroy(self.0));
+ }
+}
+
+pub trait SafeRepr {}
+impl SafeRepr for u8 {}
+impl SafeRepr for i8 {}
+impl SafeRepr for u16 {}
+impl SafeRepr for i16 {}
+impl SafeRepr for u32 {}
+impl SafeRepr for i32 {}
+impl SafeRepr for u64 {}
+impl SafeRepr for i64 {}
+impl SafeRepr for f32 {}
+impl SafeRepr for f64 {}
+
+pub struct DeviceBuffer<T: SafeRepr> {
+ ptr: *mut c_void,
+ ctx: sys::ze_context_handle_t,
+ len: usize,
+ marker: PhantomData<T>,
+}
+
+impl<T: SafeRepr> DeviceBuffer<T> {
+ pub unsafe fn as_ffi(&self) -> *mut c_void {
+ self.ptr
+ }
+ pub unsafe fn from_ffi(ctx: sys::ze_context_handle_t, ptr: *mut c_void, len: usize) -> Self {
+ let marker = PhantomData::<T>;
+ Self {
+ ptr,
+ ctx,
+ len,
+ marker,
+ }
+ }
+
+ pub fn new(ctx: &mut Context, dev: &Device, len: usize) -> Result<Self> {
+ let desc = sys::_ze_device_mem_alloc_desc_t {
+ stype: sys::ze_structure_type_t::ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC,
+ pNext: ptr::null(),
+ flags: sys::ze_device_mem_alloc_flags_t(0),
+ ordinal: 0,
+ };
+ let mut result = ptr::null_mut();
+ check!(sys::zeMemAllocDevice(
+ ctx.0,
+ &desc,
+ len * mem::size_of::<T>(),
+ mem::align_of::<T>(),
+ dev.0,
+ &mut result
+ ));
+ Ok(unsafe { Self::from_ffi(ctx.0, result, len) })
+ }
+
+ pub fn len(&self) -> usize {
+ self.len
+ }
+}
+
+impl<T: SafeRepr> Drop for DeviceBuffer<T> {
+ #[allow(unused_must_use)]
+ fn drop(&mut self) {
+ check_panic! { sys::zeMemFree(self.ctx, self.ptr) };
+ }
+}
+
+pub struct CommandList<'a>(sys::ze_command_list_handle_t, PhantomData<&'a ()>);
+
+impl<'a> CommandList<'a> {
+ pub unsafe fn as_ffi(&self) -> sys::ze_command_list_handle_t {
+ self.0
+ }
+ pub unsafe fn from_ffi(x: sys::ze_command_list_handle_t) -> Self {
+ Self(x, PhantomData)
+ }
+
+ pub fn new(ctx: &mut Context, dev: &Device) -> Result<Self> {
+ let desc = sys::ze_command_list_desc_t {
+ stype: sys::_ze_structure_type_t::ZE_STRUCTURE_TYPE_COMMAND_LIST_DESC,
+ commandQueueGroupOrdinal: 0,
+ pNext: ptr::null(),
+ flags: sys::ze_command_list_flags_t(0),
+ };
+ let mut result: sys::ze_command_list_handle_t = ptr::null_mut();
+ check!(sys::zeCommandListCreate(ctx.0, dev.0, &desc, &mut result));
+ Ok(Self(result, PhantomData))
+ }
+
+ pub fn append_memory_copy<
+ T: 'a,
+ Dst: Into<BufferPtrMut<'a, T>>,
+ Src: Into<BufferPtr<'a, T>>,
+ >(
+ &mut self,
+ dst: Dst,
+ src: Src,
+ signal: Option<&mut Event<'a>>,
+ wait: &mut [Event<'a>],
+ ) -> Result<()> {
+ let dst = dst.into();
+ let src = src.into();
+ let elements = std::cmp::min(dst.len(), src.len());
+ let length = elements * mem::size_of::<T>();
+ unsafe { self.append_memory_copy_unsafe(dst.get(), src.get(), length, signal, wait) }
+ }
+
+ pub unsafe fn append_memory_copy_unsafe(
+ &mut self,
+ dst: *mut c_void,
+ src: *const c_void,
+ length: usize,
+ signal: Option<&mut Event<'a>>,
+ wait: &mut [Event<'a>],
+ ) -> Result<()> {
+ let signal_event = signal.map(|e| e.0).unwrap_or(ptr::null_mut());
+ let (wait_len, wait_ptr) = Event::raw_slice(wait);
+ check!(sys::zeCommandListAppendMemoryCopy(
+ self.0,
+ dst,
+ src,
+ length,
+ signal_event,
+ wait_len,
+ wait_ptr
+ ));
+ Ok(())
+ }
+
+ pub fn append_memory_fill<T>(
+ &mut self,
+ dst: BufferPtrMut<'a, T>,
+ pattern: u8,
+ signal: Option<&mut Event<'a>>,
+ wait: &mut [Event<'a>],
+ ) -> Result<()> {
+ let raw_pattern = &pattern as *const u8 as *const _;
+ let signal_event = signal.map(|e| e.0).unwrap_or(ptr::null_mut());
+ let (wait_len, wait_ptr) = unsafe { Event::raw_slice(wait) };
+ let byte_len = dst.len() * mem::size_of::<T>();
+ check!(sys::zeCommandListAppendMemoryFill(
+ self.0,
+ dst.get(),
+ raw_pattern,
+ mem::size_of::<u8>(),
+ byte_len,
+ signal_event,
+ wait_len,
+ wait_ptr
+ ));
+ Ok(())
+ }
+
+ pub unsafe fn append_memory_fill_unsafe<T: Copy + Sized>(
+ &mut self,
+ dst: *mut c_void,
+ pattern: &T,
+ byte_size: usize,
+ signal: Option<&mut Event<'a>>,
+ wait: &mut [Event<'a>],
+ ) -> Result<()> {
+ let signal_event = signal.map(|e| e.0).unwrap_or(ptr::null_mut());
+ let (wait_len, wait_ptr) = Event::raw_slice(wait);
+ check!(sys::zeCommandListAppendMemoryFill(
+ self.0,
+ dst,
+ pattern as *const T as *const _,
+ mem::size_of::<T>(),
+ byte_size,
+ signal_event,
+ wait_len,
+ wait_ptr
+ ));
+ Ok(())
+ }
+
+ pub fn append_launch_kernel(
+ &mut self,
+ kernel: &'a Kernel,
+ group_count: &[u32; 3],
+ signal: Option<&mut Event<'a>>,
+ wait: &mut [Event<'a>],
+ ) -> Result<()> {
+ let gr_count = sys::ze_group_count_t {
+ groupCountX: group_count[0],
+ groupCountY: group_count[1],
+ groupCountZ: group_count[2],
+ };
+ let signal_event = signal.map(|e| e.0).unwrap_or(ptr::null_mut());
+ let (wait_len, wait_ptr) = unsafe { Event::raw_slice(wait) };
+ check!(sys::zeCommandListAppendLaunchKernel(
+ self.0,
+ kernel.0,
+ &gr_count,
+ signal_event,
+ wait_len,
+ wait_ptr,
+ ));
+ Ok(())
+ }
+}
+
+impl<'a> Drop for CommandList<'a> {
+ #[allow(unused_must_use)]
+ fn drop(&mut self) {
+ check_panic! { sys::zeCommandListDestroy(self.0) };
+ }
+}
+
+pub struct FenceGuard<'a>(
+ sys::ze_fence_handle_t,
+ sys::ze_command_list_handle_t,
+ PhantomData<&'a ()>,
+);
+
+impl<'a> FenceGuard<'a> {
+ fn new(q: &'a CommandQueue, cmd_list: sys::ze_command_list_handle_t) -> Result<Self> {
+ let desc = sys::_ze_fence_desc_t {
+ stype: sys::ze_structure_type_t::ZE_STRUCTURE_TYPE_FENCE_DESC,
+ pNext: ptr::null(),
+ flags: sys::ze_fence_flags_t(0),
+ };
+ let mut result = ptr::null_mut();
+ check!(sys::zeFenceCreate(q.0, &desc, &mut result));
+ Ok(FenceGuard(result, cmd_list, PhantomData))
+ }
+}
+
+impl<'a> Drop for FenceGuard<'a> {
+ #[allow(unused_must_use)]
+ fn drop(&mut self) {
+ check_panic! { sys::zeFenceHostSynchronize(self.0, u64::max_value()) };
+ check_panic! { sys::zeFenceDestroy(self.0) };
+ check_panic! { sys::zeCommandListDestroy(self.1) };
+ }
+}
+
+#[derive(Copy, Clone)]
+pub struct BufferPtr<'a, T> {
+ ptr: *const c_void,
+ marker: PhantomData<&'a T>,
+ elems: usize,
+}
+
+impl<'a, T> BufferPtr<'a, T> {
+ pub unsafe fn get(self) -> *const c_void {
+ return self.ptr;
+ }
+
+ pub fn len(&self) -> usize {
+ self.elems
+ }
+}
+
+impl<'a, T> From<&'a [T]> for BufferPtr<'a, T> {
+ fn from(s: &'a [T]) -> Self {
+ BufferPtr {
+ ptr: s.as_ptr() as *const _,
+ marker: PhantomData,
+ elems: s.len(),
+ }
+ }
+}
+
+impl<'a, T: SafeRepr> From<&'a DeviceBuffer<T>> for BufferPtr<'a, T> {
+ fn from(b: &'a DeviceBuffer<T>) -> Self {
+ BufferPtr {
+ ptr: b.ptr as *const _,
+ marker: PhantomData,
+ elems: b.len(),
+ }
+ }
+}
+
+#[derive(Copy, Clone)]
+pub struct BufferPtrMut<'a, T> {
+ ptr: *mut c_void,
+ marker: PhantomData<&'a mut T>,
+ elems: usize,
+}
+
+impl<'a, T> BufferPtrMut<'a, T> {
+ pub unsafe fn get(self) -> *mut c_void {
+ return self.ptr;
+ }
+
+ pub fn len(&self) -> usize {
+ self.elems
+ }
+}
+
+impl<'a, T> From<&'a mut [T]> for BufferPtrMut<'a, T> {
+ fn from(s: &'a mut [T]) -> Self {
+ BufferPtrMut {
+ ptr: s.as_mut_ptr() as *mut _,
+ marker: PhantomData,
+ elems: s.len(),
+ }
+ }
+}
+
+impl<'a, T: SafeRepr> From<&'a mut DeviceBuffer<T>> for BufferPtrMut<'a, T> {
+ fn from(b: &'a mut DeviceBuffer<T>) -> Self {
+ BufferPtrMut {
+ ptr: b.ptr as *mut _,
+ marker: PhantomData,
+ elems: b.len(),
+ }
+ }
+}
+
+impl<'a, T: SafeRepr> From<BufferPtrMut<'a, T>> for BufferPtr<'a, T> {
+ fn from(b: BufferPtrMut<'a, T>) -> Self {
+ BufferPtr {
+ ptr: b.ptr,
+ marker: PhantomData,
+ elems: b.len(),
+ }
+ }
+}
+pub struct EventPool<'a>(sys::ze_event_pool_handle_t, PhantomData<&'a ()>);
+
+impl<'a> EventPool<'a> {
+ pub unsafe fn as_ffi(&self) -> sys::ze_event_pool_handle_t {
+ self.0
+ }
+ pub unsafe fn from_ffi(x: sys::ze_event_pool_handle_t) -> Self {
+ Self(x, PhantomData)
+ }
+ pub fn new(ctx: &mut Context, count: u32, dev: Option<&[&'a Device]>) -> Result<Self> {
+ let desc = sys::ze_event_pool_desc_t {
+ stype: sys::ze_structure_type_t::ZE_STRUCTURE_TYPE_EVENT_POOL_DESC,
+ pNext: ptr::null(),
+ flags: sys::ze_event_pool_flags_t(0),
+ count: count,
+ };
+ let mut dev = dev.map(|d| d.iter().map(|d| d.0).collect::<Vec<_>>());
+ let dev_len = dev.as_ref().map_or(0, |d| d.len() as u32);
+ let dev_ptr = dev.as_mut().map_or(ptr::null_mut(), |d| d.as_mut_ptr());
+ let mut result = ptr::null_mut();
+ check!(sys::zeEventPoolCreate(
+ ctx.0,
+ &desc,
+ dev_len,
+ dev_ptr,
+ &mut result
+ ));
+ Ok(Self(result, PhantomData))
+ }
+}
+
+impl<'a> Drop for EventPool<'a> {
+ #[allow(unused_must_use)]
+ fn drop(&mut self) {
+ check_panic! { sys::zeEventPoolDestroy(self.0) };
+ }
+}
+
+pub struct Event<'a>(sys::ze_event_handle_t, PhantomData<&'a ()>);
+
+impl<'a> Event<'a> {
+ pub unsafe fn as_ffi(&self) -> sys::ze_event_handle_t {
+ self.0
+ }
+
+ pub unsafe fn from_ffi(x: sys::ze_event_handle_t) -> Self {
+ Self(x, PhantomData)
+ }
+
+ pub fn new(pool: &'a EventPool, index: u32) -> Result<Self> {
+ let desc = sys::ze_event_desc_t {
+ stype: sys::ze_structure_type_t::ZE_STRUCTURE_TYPE_EVENT_DESC,
+ pNext: ptr::null(),
+ index: index,
+ signal: sys::ze_event_scope_flags_t(0),
+ wait: sys::ze_event_scope_flags_t(0),
+ };
+ let mut result = ptr::null_mut();
+ check!(sys::zeEventCreate(pool.0, &desc, &mut result));
+ Ok(Self(result, PhantomData))
+ }
+
+ unsafe fn raw_slice(e: &mut [Event]) -> (u32, *mut sys::ze_event_handle_t) {
+ let ptr = if e.len() == 0 {
+ ptr::null_mut()
+ } else {
+ e.as_mut_ptr()
+ };
+ (e.len() as u32, ptr as *mut sys::ze_event_handle_t)
+ }
+}
+
+impl<'a> Drop for Event<'a> {
+ #[allow(unused_must_use)]
+ fn drop(&mut self) {
+ check_panic! { sys::zeEventDestroy(self.0) };
+ }
+}
+
+pub struct Kernel<'a>(sys::ze_kernel_handle_t, PhantomData<&'a ()>);
+
+impl<'a> Kernel<'a> {
+ pub unsafe fn as_ffi(&self) -> sys::ze_kernel_handle_t {
+ self.0
+ }
+
+ pub unsafe fn from_ffi(x: sys::ze_kernel_handle_t) -> Self {
+ Self(x, PhantomData)
+ }
+
+ pub fn new_resident(module: &'a Module, name: &CStr) -> Result<Self> {
+ let desc = sys::ze_kernel_desc_t {
+ stype: sys::ze_structure_type_t::ZE_STRUCTURE_TYPE_KERNEL_DESC,
+ pNext: ptr::null(),
+ flags: sys::ze_kernel_flags_t::ZE_KERNEL_FLAG_FORCE_RESIDENCY,
+ pKernelName: name.as_ptr() as *const _,
+ };
+ let mut result = ptr::null_mut();
+ check!(sys::zeKernelCreate(module.0, &desc, &mut result));
+ Ok(Self(result, PhantomData))
+ }
+
+ pub fn set_indirect_access(
+ &mut self,
+ flags: sys::ze_kernel_indirect_access_flags_t,
+ ) -> Result<()> {
+ check!(sys::zeKernelSetIndirectAccess(self.0, flags));
+ Ok(())
+ }
+
+ pub fn set_arg_buffer<T: 'a, Buff: Into<BufferPtr<'a, T>>>(
+ &self,
+ index: u32,
+ buff: Buff,
+ ) -> Result<()> {
+ let ptr = unsafe { buff.into().get() };
+ check!(sys::zeKernelSetArgumentValue(
+ self.0,
+ index,
+ mem::size_of::<*const ()>(),
+ &ptr as *const _ as *const _,
+ ));
+ Ok(())
+ }
+
+ pub fn set_arg_scalar<T: Copy>(&self, index: u32, value: &T) -> Result<()> {
+ check!(sys::zeKernelSetArgumentValue(
+ self.0,
+ index,
+ mem::size_of::<T>(),
+ value as *const T as *const _,
+ ));
+ Ok(())
+ }
+
+ pub unsafe fn set_arg_raw(&self, index: u32, size: usize, value: *const c_void) -> Result<()> {
+ check!(sys::zeKernelSetArgumentValue(self.0, index, size, value));
+ Ok(())
+ }
+
+ pub fn set_group_size(&self, x: u32, y: u32, z: u32) -> Result<()> {
+ check!(sys::zeKernelSetGroupSize(self.0, x, y, z));
+ Ok(())
+ }
+
+ pub fn get_properties(&self) -> Result<Box<sys::ze_kernel_properties_t>> {
+ let mut props = Box::new(unsafe { mem::zeroed::<sys::ze_kernel_properties_t>() });
+ check!(sys::zeKernelGetProperties(self.0, props.as_mut() as *mut _));
+ Ok(props)
+ }
+}
+
+impl<'a> Drop for Kernel<'a> {
+ #[allow(unused_must_use)]
+ fn drop(&mut self) {
+ check_panic! { sys::zeKernelDestroy(self.0) };
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn event_has_correct_layout() {
+ assert_eq!(
+ mem::size_of::<Event>(),
+ mem::size_of::<sys::ze_event_handle_t>()
+ );
+ }
+}
diff --git a/ptx/Cargo.toml b/ptx/Cargo.toml
new file mode 100644
index 0000000..409cd1f
--- /dev/null
+++ b/ptx/Cargo.toml
@@ -0,0 +1,27 @@
+[package]
+name = "ptx"
+version = "0.0.0"
+authors = ["Andrzej Janik <[email protected]>"]
+edition = "2018"
+
+[lib]
+
+[dependencies]
+lalrpop-util = "0.19"
+regex = "1"
+rspirv = "0.6"
+spirv_headers = "~1.4.2"
+quick-error = "1.2"
+bit-vec = "0.6"
+half ="1.6"
+bitflags = "1.2"
+
+[build-dependencies.lalrpop]
+version = "0.19"
+features = ["lexer"]
+
+[dev-dependencies]
+level_zero-sys = { path = "../level_zero-sys" }
+level_zero = { path = "../level_zero" }
+spirv_tools-sys = { path = "../spirv_tools-sys" }
+paste = "1.0"
diff --git a/ptx/build.rs b/ptx/build.rs
new file mode 100644
index 0000000..42c5d59
--- /dev/null
+++ b/ptx/build.rs
@@ -0,0 +1,5 @@
+extern crate lalrpop;
+
+fn main() {
+ lalrpop::process_root().unwrap();
+} \ No newline at end of file
diff --git a/ptx/lib/zluda_ptx_impl.cl b/ptx/lib/zluda_ptx_impl.cl
new file mode 100644
index 0000000..94d02ec
--- /dev/null
+++ b/ptx/lib/zluda_ptx_impl.cl
@@ -0,0 +1,146 @@
+// Every time this file changes it must te rebuilt:
+// ocloc -file zluda_ptx_impl.cl -64 -options "-cl-std=CL2.0 -Dcl_intel_bit_instructions" -out_dir . -device kbl -output_no_suffix -spv_only
+// Additionally you should strip names:
+// spirv-opt --strip-debug zluda_ptx_impl.spv -o zluda_ptx_impl.spv
+
+#define FUNC(NAME) __zluda_ptx_impl__ ## NAME
+
+#define atomic_inc(NAME, SUCCESS, FAILURE, SCOPE, SPACE) \
+ uint FUNC(NAME)(SPACE uint* ptr, uint threshold) { \
+ uint expected = *ptr; \
+ uint desired; \
+ do { \
+ desired = (expected >= threshold) ? 0 : expected + 1; \
+ } while (!atomic_compare_exchange_strong_explicit((volatile SPACE atomic_uint*)ptr, &expected, desired, SUCCESS, FAILURE, SCOPE)); \
+ return expected; \
+ }
+
+#define atomic_dec(NAME, SUCCESS, FAILURE, SCOPE, SPACE) \
+ uint FUNC(NAME)(SPACE uint* ptr, uint threshold) { \
+ uint expected = *ptr; \
+ uint desired; \
+ do { \
+ desired = (expected == 0 || expected > threshold) ? threshold : expected - 1; \
+ } while (!atomic_compare_exchange_strong_explicit((volatile SPACE atomic_uint*)ptr, &expected, desired, SUCCESS, FAILURE, SCOPE)); \
+ return expected; \
+ }
+
+// We are doing all this mess instead of accepting memory_order and memory_scope parameters
+// because ocloc emits broken (failing spirv-dis) SPIR-V when memory_order or memory_scope is a parameter
+
+// atom.inc
+atomic_inc(atom_relaxed_cta_generic_inc, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group, );
+atomic_inc(atom_acquire_cta_generic_inc, memory_order_acquire, memory_order_acquire, memory_scope_work_group, );
+atomic_inc(atom_release_cta_generic_inc, memory_order_release, memory_order_acquire, memory_scope_work_group, );
+atomic_inc(atom_acq_rel_cta_generic_inc, memory_order_acq_rel, memory_order_acquire, memory_scope_work_group, );
+
+atomic_inc(atom_relaxed_gpu_generic_inc, memory_order_relaxed, memory_order_relaxed, memory_scope_device, );
+atomic_inc(atom_acquire_gpu_generic_inc, memory_order_acquire, memory_order_acquire, memory_scope_device, );
+atomic_inc(atom_release_gpu_generic_inc, memory_order_release, memory_order_acquire, memory_scope_device, );
+atomic_inc(atom_acq_rel_gpu_generic_inc, memory_order_acq_rel, memory_order_acquire, memory_scope_device, );
+
+atomic_inc(atom_relaxed_sys_generic_inc, memory_order_relaxed, memory_order_relaxed, memory_scope_device, );
+atomic_inc(atom_acquire_sys_generic_inc, memory_order_acquire, memory_order_acquire, memory_scope_device, );
+atomic_inc(atom_release_sys_generic_inc, memory_order_release, memory_order_acquire, memory_scope_device, );
+atomic_inc(atom_acq_rel_sys_generic_inc, memory_order_acq_rel, memory_order_acquire, memory_scope_device, );
+
+atomic_inc(atom_relaxed_cta_global_inc, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group, __global);
+atomic_inc(atom_acquire_cta_global_inc, memory_order_acquire, memory_order_acquire, memory_scope_work_group, __global);
+atomic_inc(atom_release_cta_global_inc, memory_order_release, memory_order_acquire, memory_scope_work_group, __global);
+atomic_inc(atom_acq_rel_cta_global_inc, memory_order_acq_rel, memory_order_acquire, memory_scope_work_group, __global);
+
+atomic_inc(atom_relaxed_gpu_global_inc, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __global);
+atomic_inc(atom_acquire_gpu_global_inc, memory_order_acquire, memory_order_acquire, memory_scope_device, __global);
+atomic_inc(atom_release_gpu_global_inc, memory_order_release, memory_order_acquire, memory_scope_device, __global);
+atomic_inc(atom_acq_rel_gpu_global_inc, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __global);
+
+atomic_inc(atom_relaxed_sys_global_inc, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __global);
+atomic_inc(atom_acquire_sys_global_inc, memory_order_acquire, memory_order_acquire, memory_scope_device, __global);
+atomic_inc(atom_release_sys_global_inc, memory_order_release, memory_order_acquire, memory_scope_device, __global);
+atomic_inc(atom_acq_rel_sys_global_inc, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __global);
+
+atomic_inc(atom_relaxed_cta_shared_inc, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group, __local);
+atomic_inc(atom_acquire_cta_shared_inc, memory_order_acquire, memory_order_acquire, memory_scope_work_group, __local);
+atomic_inc(atom_release_cta_shared_inc, memory_order_release, memory_order_acquire, memory_scope_work_group, __local);
+atomic_inc(atom_acq_rel_cta_shared_inc, memory_order_acq_rel, memory_order_acquire, memory_scope_work_group, __local);
+
+atomic_inc(atom_relaxed_gpu_shared_inc, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __local);
+atomic_inc(atom_acquire_gpu_shared_inc, memory_order_acquire, memory_order_acquire, memory_scope_device, __local);
+atomic_inc(atom_release_gpu_shared_inc, memory_order_release, memory_order_acquire, memory_scope_device, __local);
+atomic_inc(atom_acq_rel_gpu_shared_inc, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __local);
+
+atomic_inc(atom_relaxed_sys_shared_inc, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __local);
+atomic_inc(atom_acquire_sys_shared_inc, memory_order_acquire, memory_order_acquire, memory_scope_device, __local);
+atomic_inc(atom_release_sys_shared_inc, memory_order_release, memory_order_acquire, memory_scope_device, __local);
+atomic_inc(atom_acq_rel_sys_shared_inc, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __local);
+
+// atom.dec
+atomic_dec(atom_relaxed_cta_generic_dec, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group, );
+atomic_dec(atom_acquire_cta_generic_dec, memory_order_acquire, memory_order_acquire, memory_scope_work_group, );
+atomic_dec(atom_release_cta_generic_dec, memory_order_release, memory_order_acquire, memory_scope_work_group, );
+atomic_dec(atom_acq_rel_cta_generic_dec, memory_order_acq_rel, memory_order_acquire, memory_scope_work_group, );
+
+atomic_dec(atom_relaxed_gpu_generic_dec, memory_order_relaxed, memory_order_relaxed, memory_scope_device, );
+atomic_dec(atom_acquire_gpu_generic_dec, memory_order_acquire, memory_order_acquire, memory_scope_device, );
+atomic_dec(atom_release_gpu_generic_dec, memory_order_release, memory_order_acquire, memory_scope_device, );
+atomic_dec(atom_acq_rel_gpu_generic_dec, memory_order_acq_rel, memory_order_acquire, memory_scope_device, );
+
+atomic_dec(atom_relaxed_sys_generic_dec, memory_order_relaxed, memory_order_relaxed, memory_scope_device, );
+atomic_dec(atom_acquire_sys_generic_dec, memory_order_acquire, memory_order_acquire, memory_scope_device, );
+atomic_dec(atom_release_sys_generic_dec, memory_order_release, memory_order_acquire, memory_scope_device, );
+atomic_dec(atom_acq_rel_sys_generic_dec, memory_order_acq_rel, memory_order_acquire, memory_scope_device, );
+
+atomic_dec(atom_relaxed_cta_global_dec, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group, __global);
+atomic_dec(atom_acquire_cta_global_dec, memory_order_acquire, memory_order_acquire, memory_scope_work_group, __global);
+atomic_dec(atom_release_cta_global_dec, memory_order_release, memory_order_acquire, memory_scope_work_group, __global);
+atomic_dec(atom_acq_rel_cta_global_dec, memory_order_acq_rel, memory_order_acquire, memory_scope_work_group, __global);
+
+atomic_dec(atom_relaxed_gpu_global_dec, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __global);
+atomic_dec(atom_acquire_gpu_global_dec, memory_order_acquire, memory_order_acquire, memory_scope_device, __global);
+atomic_dec(atom_release_gpu_global_dec, memory_order_release, memory_order_acquire, memory_scope_device, __global);
+atomic_dec(atom_acq_rel_gpu_global_dec, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __global);
+
+atomic_dec(atom_relaxed_sys_global_dec, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __global);
+atomic_dec(atom_acquire_sys_global_dec, memory_order_acquire, memory_order_acquire, memory_scope_device, __global);
+atomic_dec(atom_release_sys_global_dec, memory_order_release, memory_order_acquire, memory_scope_device, __global);
+atomic_dec(atom_acq_rel_sys_global_dec, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __global);
+
+atomic_dec(atom_relaxed_cta_shared_dec, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group, __local);
+atomic_dec(atom_acquire_cta_shared_dec, memory_order_acquire, memory_order_acquire, memory_scope_work_group, __local);
+atomic_dec(atom_release_cta_shared_dec, memory_order_release, memory_order_acquire, memory_scope_work_group, __local);
+atomic_dec(atom_acq_rel_cta_shared_dec, memory_order_acq_rel, memory_order_acquire, memory_scope_work_group, __local);
+
+atomic_dec(atom_relaxed_gpu_shared_dec, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __local);
+atomic_dec(atom_acquire_gpu_shared_dec, memory_order_acquire, memory_order_acquire, memory_scope_device, __local);
+atomic_dec(atom_release_gpu_shared_dec, memory_order_release, memory_order_acquire, memory_scope_device, __local);
+atomic_dec(atom_acq_rel_gpu_shared_dec, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __local);
+
+atomic_dec(atom_relaxed_sys_shared_dec, memory_order_relaxed, memory_order_relaxed, memory_scope_device, __local);
+atomic_dec(atom_acquire_sys_shared_dec, memory_order_acquire, memory_order_acquire, memory_scope_device, __local);
+atomic_dec(atom_release_sys_shared_dec, memory_order_release, memory_order_acquire, memory_scope_device, __local);
+atomic_dec(atom_acq_rel_sys_shared_dec, memory_order_acq_rel, memory_order_acquire, memory_scope_device, __local);
+
+uint FUNC(bfe_u32)(uint base, uint pos, uint len) {
+ return intel_ubfe(base, pos, len);
+}
+
+ulong FUNC(bfe_u64)(ulong base, uint pos, uint len) {
+ return intel_ubfe(base, pos, len);
+}
+
+int FUNC(bfe_s32)(int base, uint pos, uint len) {
+ return intel_sbfe(base, pos, len);
+}
+
+long FUNC(bfe_s64)(long base, uint pos, uint len) {
+ return intel_sbfe(base, pos, len);
+}
+
+void FUNC(__assertfail)(
+ __private ulong* message,
+ __private ulong* file,
+ __private uint* line,
+ __private ulong* function,
+ __private ulong* charSize
+) {
+}
diff --git a/ptx/lib/zluda_ptx_impl.spv b/ptx/lib/zluda_ptx_impl.spv
new file mode 100644
index 0000000..731966e
--- /dev/null
+++ b/ptx/lib/zluda_ptx_impl.spv
Binary files differ
diff --git a/ptx/src/ast.rs b/ptx/src/ast.rs
new file mode 100644
index 0000000..aba6bda
--- /dev/null
+++ b/ptx/src/ast.rs
@@ -0,0 +1,1395 @@
+use std::convert::TryInto;
+use std::{convert::From, convert::TryFrom, mem, num::ParseFloatError, str::FromStr};
+use std::{marker::PhantomData, num::ParseIntError};
+
+use half::f16;
+
+quick_error! {
+ #[derive(Debug)]
+ pub enum PtxError {
+ ParseInt (err: ParseIntError) {
+ from()
+ display("{}", err)
+ cause(err)
+ }
+ ParseFloat (err: ParseFloatError) {
+ from()
+ display("{}", err)
+ cause(err)
+ }
+ SyntaxError {}
+ NonF32Ftz {}
+ WrongArrayType {}
+ WrongVectorElement {}
+ MultiArrayVariable {}
+ ZeroDimensionArray {}
+ ArrayInitalizer {}
+ NonExternPointer {}
+ }
+}
+
+macro_rules! sub_enum {
+ ($name:ident { $($variant:ident),+ $(,)? }) => {
+ sub_enum!{ $name : ScalarType { $($variant),+ } }
+ };
+ ($name:ident : $base_type:ident { $($variant:ident),+ $(,)? }) => {
+ #[derive(PartialEq, Eq, Clone, Copy)]
+ pub enum $name {
+ $(
+ $variant,
+ )+
+ }
+
+ impl From<$name> for $base_type {
+ fn from(t: $name) -> $base_type {
+ match t {
+ $(
+ $name::$variant => $base_type::$variant,
+ )+
+ }
+ }
+ }
+
+ impl std::convert::TryFrom<$base_type> for $name {
+ type Error = ();
+
+ fn try_from(t: $base_type) -> Result<Self, Self::Error> {
+ match t {
+ $(
+ $base_type::$variant => Ok($name::$variant),
+ )+
+ _ => Err(()),
+ }
+ }
+ }
+ };
+}
+
+macro_rules! sub_type {
+ ($type_name:ident { $($variant:ident ( $($field_type:ident),+ ) ),+ $(,)? } ) => {
+ sub_type! { $type_name : Type {
+ $(
+ $variant ($($field_type),+),
+ )+
+ }}
+ };
+ ($type_name:ident : $base_type:ident { $($variant:ident ( $($field_type:ident),+ ) ),+ $(,)? } ) => {
+ #[derive(PartialEq, Eq, Clone)]
+ pub enum $type_name {
+ $(
+ $variant ($($field_type),+),
+ )+
+ }
+
+ impl From<$type_name> for $base_type {
+ #[allow(non_snake_case)]
+ fn from(t: $type_name) -> $base_type {
+ match t {
+ $(
+ $type_name::$variant ( $($field_type),+ ) => <$base_type>::$variant ( $($field_type.into()),+),
+ )+
+ }
+ }
+ }
+
+ impl std::convert::TryFrom<$base_type> for $type_name {
+ type Error = ();
+
+ #[allow(non_snake_case)]
+ #[allow(unreachable_patterns)]
+ fn try_from(t: $base_type) -> Result<Self, Self::Error> {
+ match t {
+ $(
+ $base_type::$variant ( $($field_type),+ ) => Ok($type_name::$variant ( $($field_type.try_into().map_err(|_| ())? ),+ )),
+ )+
+ _ => Err(()),
+ }
+ }
+ }
+ };
+}
+
+sub_type! {
+ VariableRegType {
+ Scalar(ScalarType),
+ Vector(SizedScalarType, u8),
+ // Array type is used when emiting SSA statements at the start of a method
+ Array(ScalarType, VecU32),
+ // Pointer variant is used when passing around SLM pointer between
+ // function calls for dynamic SLM
+ Pointer(SizedScalarType, PointerStateSpace)
+ }
+}
+
+type VecU32 = Vec<u32>;
+
+sub_type! {
+ VariableLocalType {
+ Scalar(SizedScalarType),
+ Vector(SizedScalarType, u8),
+ Array(SizedScalarType, VecU32),
+ }
+}
+
+impl TryFrom<VariableGlobalType> for VariableLocalType {
+ type Error = PtxError;
+
+ fn try_from(value: VariableGlobalType) -> Result<Self, Self::Error> {
+ match value {
+ VariableGlobalType::Scalar(t) => Ok(VariableLocalType::Scalar(t)),
+ VariableGlobalType::Vector(t, len) => Ok(VariableLocalType::Vector(t, len)),
+ VariableGlobalType::Array(t, len) => Ok(VariableLocalType::Array(t, len)),
+ VariableGlobalType::Pointer(_, _) => Err(PtxError::ZeroDimensionArray),
+ }
+ }
+}
+
+sub_type! {
+ VariableGlobalType {
+ Scalar(SizedScalarType),
+ Vector(SizedScalarType, u8),
+ Array(SizedScalarType, VecU32),
+ Pointer(SizedScalarType, PointerStateSpace),
+ }
+}
+
+// For some weird reson this is illegal:
+// .param .f16x2 foobar;
+// but this is legal:
+// .param .f16x2 foobar[1];
+// even more interestingly this is legal, but only in .func (not in .entry):
+// .param .b32 foobar[]
+sub_type! {
+ VariableParamType {
+ Scalar(LdStScalarType),
+ Array(SizedScalarType, VecU32),
+ Pointer(SizedScalarType, PointerStateSpace),
+ }
+}
+
+sub_enum!(SizedScalarType {
+ B8,
+ B16,
+ B32,
+ B64,
+ U8,
+ U16,
+ U32,
+ U64,
+ S8,
+ S16,
+ S32,
+ S64,
+ F16,
+ F16x2,
+ F32,
+ F64,
+});
+
+sub_enum!(LdStScalarType {
+ B8,
+ B16,
+ B32,
+ B64,
+ U8,
+ U16,
+ U32,
+ U64,
+ S8,
+ S16,
+ S32,
+ S64,
+ F16,
+ F32,
+ F64,
+});
+
+sub_enum!(SelpType {
+ B16,
+ B32,
+ B64,
+ U16,
+ U32,
+ U64,
+ S16,
+ S32,
+ S64,
+ F32,
+ F64,
+});
+
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub enum BarDetails {
+ SyncAligned,
+}
+
+pub trait UnwrapWithVec<E, To> {
+ fn unwrap_with(self, errs: &mut Vec<E>) -> To;
+}
+
+impl<R: Default, EFrom: std::convert::Into<EInto>, EInto> UnwrapWithVec<EInto, R>
+ for Result<R, EFrom>
+{
+ fn unwrap_with(self, errs: &mut Vec<EInto>) -> R {
+ self.unwrap_or_else(|e| {
+ errs.push(e.into());
+ R::default()
+ })
+ }
+}
+
+impl<
+ R1: Default,
+ EFrom1: std::convert::Into<EInto>,
+ R2: Default,
+ EFrom2: std::convert::Into<EInto>,
+ EInto,
+ > UnwrapWithVec<EInto, (R1, R2)> for (Result<R1, EFrom1>, Result<R2, EFrom2>)
+{
+ fn unwrap_with(self, errs: &mut Vec<EInto>) -> (R1, R2) {
+ let (x, y) = self;
+ let r1 = x.unwrap_with(errs);
+ let r2 = y.unwrap_with(errs);
+ (r1, r2)
+ }
+}
+
+pub struct Module<'a> {
+ pub version: (u8, u8),
+ pub directives: Vec<Directive<'a, ParsedArgParams<'a>>>,
+}
+
+pub enum Directive<'a, P: ArgParams> {
+ Variable(Variable<VariableType, P::Id>),
+ Method(Function<'a, &'a str, Statement<P>>),
+}
+
+pub enum MethodDecl<'a, ID> {
+ Func(Vec<FnArgument<ID>>, ID, Vec<FnArgument<ID>>),
+ Kernel {
+ name: &'a str,
+ in_args: Vec<KernelArgument<ID>>,
+ },
+}
+
+pub type FnArgument<ID> = Variable<FnArgumentType, ID>;
+pub type KernelArgument<ID> = Variable<KernelArgumentType, ID>;
+
+pub struct Function<'a, ID, S> {
+ pub func_directive: MethodDecl<'a, ID>,
+ pub body: Option<Vec<S>>,
+}
+
+pub type ParsedFunction<'a> = Function<'a, &'a str, Statement<ParsedArgParams<'a>>>;
+
+#[derive(PartialEq, Eq, Clone)]
+pub enum FnArgumentType {
+ Reg(VariableRegType),
+ Param(VariableParamType),
+ Shared,
+}
+#[derive(PartialEq, Eq, Clone)]
+pub enum KernelArgumentType {
+ Normal(VariableParamType),
+ Shared,
+}
+
+impl FnArgumentType {
+ pub fn to_type(&self, is_kernel: bool) -> Type {
+ if is_kernel {
+ self.to_kernel_type()
+ } else {
+ self.to_func_type()
+ }
+ }
+
+ pub fn to_kernel_type(&self) -> Type {
+ match self {
+ FnArgumentType::Reg(x) => x.clone().into(),
+ FnArgumentType::Param(x) => x.clone().into(),
+ FnArgumentType::Shared => {
+ Type::Pointer(PointerType::Scalar(ScalarType::B8), LdStateSpace::Shared)
+ }
+ }
+ }
+
+ pub fn to_func_type(&self) -> Type {
+ match self {
+ FnArgumentType::Reg(x) => x.clone().into(),
+ FnArgumentType::Param(VariableParamType::Scalar(t)) => {
+ Type::Pointer(PointerType::Scalar((*t).into()), LdStateSpace::Param)
+ }
+ FnArgumentType::Param(VariableParamType::Array(t, dims)) => Type::Pointer(
+ PointerType::Array((*t).into(), dims.clone()),
+ LdStateSpace::Param,
+ ),
+ FnArgumentType::Param(VariableParamType::Pointer(t, space)) => Type::Pointer(
+ PointerType::Pointer((*t).into(), (*space).into()),
+ LdStateSpace::Param,
+ ),
+ FnArgumentType::Shared => {
+ Type::Pointer(PointerType::Scalar(ScalarType::B8), LdStateSpace::Shared)
+ }
+ }
+ }
+
+ pub fn is_param(&self) -> bool {
+ match self {
+ FnArgumentType::Param(_) => true,
+ _ => false,
+ }
+ }
+}
+
+sub_enum!(
+ PointerStateSpace : LdStateSpace {
+ Generic,
+ Global,
+ Const,
+ Shared,
+ Param,
+ }
+);
+
+#[derive(PartialEq, Eq, Clone)]
+pub enum Type {
+ Scalar(ScalarType),
+ Vector(ScalarType, u8),
+ Array(ScalarType, Vec<u32>),
+ Pointer(PointerType, LdStateSpace),
+}
+
+#[derive(PartialEq, Eq, Clone)]
+pub enum PointerType {
+ Scalar(ScalarType),
+ Vector(ScalarType, u8),
+ Array(ScalarType, VecU32),
+ Pointer(ScalarType, LdStateSpace),
+}
+
+impl From<SizedScalarType> for PointerType {
+ fn from(t: SizedScalarType) -> Self {
+ PointerType::Scalar(t.into())
+ }
+}
+
+impl TryFrom<PointerType> for SizedScalarType {
+ type Error = ();
+
+ fn try_from(value: PointerType) -> Result<Self, Self::Error> {
+ match value {
+ PointerType::Scalar(t) => Ok(t.try_into()?),
+ PointerType::Vector(_, _) => Err(()),
+ PointerType::Array(_, _) => Err(()),
+ PointerType::Pointer(_, _) => Err(()),
+ }
+ }
+}
+
+#[derive(PartialEq, Eq, Hash, Clone, Copy)]
+pub enum ScalarType {
+ B8,
+ B16,
+ B32,
+ B64,
+ U8,
+ U16,
+ U32,
+ U64,
+ S8,
+ S16,
+ S32,
+ S64,
+ F16,
+ F32,
+ F64,
+ F16x2,
+ Pred,
+}
+
+sub_enum!(IntType {
+ U8,
+ U16,
+ U32,
+ U64,
+ S8,
+ S16,
+ S32,
+ S64
+});
+
+sub_enum!(BitType { B8, B16, B32, B64 });
+
+sub_enum!(UIntType { U8, U16, U32, U64 });
+
+sub_enum!(SIntType { S8, S16, S32, S64 });
+
+impl IntType {
+ pub fn is_signed(self) -> bool {
+ match self {
+ IntType::U8 | IntType::U16 | IntType::U32 | IntType::U64 => false,
+ IntType::S8 | IntType::S16 | IntType::S32 | IntType::S64 => true,
+ }
+ }
+
+ pub fn width(self) -> u8 {
+ match self {
+ IntType::U8 => 1,
+ IntType::U16 => 2,
+ IntType::U32 => 4,
+ IntType::U64 => 8,
+ IntType::S8 => 1,
+ IntType::S16 => 2,
+ IntType::S32 => 4,
+ IntType::S64 => 8,
+ }
+ }
+}
+
+sub_enum!(FloatType {
+ F16,
+ F16x2,
+ F32,
+ F64
+});
+
+impl ScalarType {
+ pub fn size_of(self) -> u8 {
+ match self {
+ ScalarType::U8 => 1,
+ ScalarType::S8 => 1,
+ ScalarType::B8 => 1,
+ ScalarType::U16 => 2,
+ ScalarType::S16 => 2,
+ ScalarType::B16 => 2,
+ ScalarType::F16 => 2,
+ ScalarType::U32 => 4,
+ ScalarType::S32 => 4,
+ ScalarType::B32 => 4,
+ ScalarType::F32 => 4,
+ ScalarType::U64 => 8,
+ ScalarType::S64 => 8,
+ ScalarType::B64 => 8,
+ ScalarType::F64 => 8,
+ ScalarType::F16x2 => 4,
+ ScalarType::Pred => 1,
+ }
+ }
+}
+
+impl Default for ScalarType {
+ fn default() -> Self {
+ ScalarType::B8
+ }
+}
+
+pub enum Statement<P: ArgParams> {
+ Label(P::Id),
+ Variable(MultiVariable<P::Id>),
+ Instruction(Option<PredAt<P::Id>>, Instruction<P>),
+ Block(Vec<Statement<P>>),
+}
+
+pub struct MultiVariable<ID> {
+ pub var: Variable<VariableType, ID>,
+ pub count: Option<u32>,
+}
+
+#[derive(Clone)]
+pub struct Variable<T, ID> {
+ pub align: Option<u32>,
+ pub v_type: T,
+ pub name: ID,
+ pub array_init: Vec<u8>,
+}
+
+#[derive(Eq, PartialEq, Clone)]
+pub enum VariableType {
+ Reg(VariableRegType),
+ Local(VariableLocalType),
+ Param(VariableParamType),
+ Global(VariableGlobalType),
+ Shared(VariableGlobalType),
+}
+
+impl VariableType {
+ pub fn to_type(&self) -> (StateSpace, Type) {
+ match self {
+ VariableType::Reg(t) => (StateSpace::Reg, t.clone().into()),
+ VariableType::Local(t) => (StateSpace::Local, t.clone().into()),
+ VariableType::Param(t) => (StateSpace::Param, t.clone().into()),
+ VariableType::Global(t) => (StateSpace::Global, t.clone().into()),
+ VariableType::Shared(t) => (StateSpace::Shared, t.clone().into()),
+ }
+ }
+}
+
+impl From<VariableType> for Type {
+ fn from(t: VariableType) -> Self {
+ match t {
+ VariableType::Reg(t) => t.into(),
+ VariableType::Local(t) => t.into(),
+ VariableType::Param(t) => t.into(),
+ VariableType::Global(t) => t.into(),
+ VariableType::Shared(t) => t.into(),
+ }
+ }
+}
+
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub enum StateSpace {
+ Reg,
+ Const,
+ Global,
+ Local,
+ Shared,
+ Param,
+}
+
+pub struct PredAt<ID> {
+ pub not: bool,
+ pub label: ID,
+}
+
+pub enum Instruction<P: ArgParams> {
+ Ld(LdDetails, Arg2Ld<P>),
+ Mov(MovDetails, Arg2Mov<P>),
+ Mul(MulDetails, Arg3<P>),
+ Add(ArithDetails, Arg3<P>),
+ Setp(SetpData, Arg4Setp<P>),
+ SetpBool(SetpBoolData, Arg5Setp<P>),
+ Not(BooleanType, Arg2<P>),
+ Bra(BraData, Arg1<P>),
+ Cvt(CvtDetails, Arg2<P>),
+ Cvta(CvtaDetails, Arg2<P>),
+ Shl(ShlType, Arg3<P>),
+ Shr(ShrType, Arg3<P>),
+ St(StData, Arg2St<P>),
+ Ret(RetData),
+ Call(CallInst<P>),
+ Abs(AbsDetails, Arg2<P>),
+ Mad(MulDetails, Arg4<P>),
+ Or(BooleanType, Arg3<P>),
+ Sub(ArithDetails, Arg3<P>),
+ Min(MinMaxDetails, Arg3<P>),
+ Max(MinMaxDetails, Arg3<P>),
+ Rcp(RcpDetails, Arg2<P>),
+ And(BooleanType, Arg3<P>),
+ Selp(SelpType, Arg4<P>),
+ Bar(BarDetails, Arg1Bar<P>),
+ Atom(AtomDetails, Arg3<P>),
+ AtomCas(AtomCasDetails, Arg4<P>),
+ Div(DivDetails, Arg3<P>),
+ Sqrt(SqrtDetails, Arg2<P>),
+ Rsqrt(RsqrtDetails, Arg2<P>),
+ Neg(NegDetails, Arg2<P>),
+ Sin { flush_to_zero: bool, arg: Arg2<P> },
+ Cos { flush_to_zero: bool, arg: Arg2<P> },
+ Lg2 { flush_to_zero: bool, arg: Arg2<P> },
+ Ex2 { flush_to_zero: bool, arg: Arg2<P> },
+ Clz { typ: BitType, arg: Arg2<P> },
+ Brev { typ: BitType, arg: Arg2<P> },
+ Popc { typ: BitType, arg: Arg2<P> },
+ Xor { typ: BooleanType, arg: Arg3<P> },
+ Bfe { typ: IntType, arg: Arg4<P> },
+ Rem { typ: IntType, arg: Arg3<P> },
+}
+
+#[derive(Copy, Clone)]
+pub struct MadFloatDesc {}
+
+#[derive(Copy, Clone)]
+pub struct AbsDetails {
+ pub flush_to_zero: Option<bool>,
+ pub typ: ScalarType,
+}
+#[derive(Copy, Clone)]
+pub struct RcpDetails {
+ pub rounding: Option<RoundingMode>,
+ pub flush_to_zero: Option<bool>,
+ pub is_f64: bool,
+}
+
+pub struct CallInst<P: ArgParams> {
+ pub uniform: bool,
+ pub ret_params: Vec<P::Id>,
+ pub func: P::Id,
+ pub param_list: Vec<P::Operand>,
+}
+
+pub trait ArgParams {
+ type Id;
+ type Operand;
+}
+
+pub struct ParsedArgParams<'a> {
+ _marker: PhantomData<&'a ()>,
+}
+
+impl<'a> ArgParams for ParsedArgParams<'a> {
+ type Id = &'a str;
+ type Operand = Operand<&'a str>;
+}
+
+pub struct Arg1<P: ArgParams> {
+ pub src: P::Id, // it is a jump destination, but in terms of operands it is a source operand
+}
+
+pub struct Arg1Bar<P: ArgParams> {
+ pub src: P::Operand,
+}
+
+pub struct Arg2<P: ArgParams> {
+ pub dst: P::Operand,
+ pub src: P::Operand,
+}
+pub struct Arg2Ld<P: ArgParams> {
+ pub dst: P::Operand,
+ pub src: P::Operand,
+}
+
+pub struct Arg2St<P: ArgParams> {
+ pub src1: P::Operand,
+ pub src2: P::Operand,
+}
+
+pub struct Arg2Mov<P: ArgParams> {
+ pub dst: P::Operand,
+ pub src: P::Operand,
+}
+
+pub struct Arg3<P: ArgParams> {
+ pub dst: P::Operand,
+ pub src1: P::Operand,
+ pub src2: P::Operand,
+}
+
+pub struct Arg4<P: ArgParams> {
+ pub dst: P::Operand,
+ pub src1: P::Operand,
+ pub src2: P::Operand,
+ pub src3: P::Operand,
+}
+
+pub struct Arg4Setp<P: ArgParams> {
+ pub dst1: P::Id,
+ pub dst2: Option<P::Id>,
+ pub src1: P::Operand,
+ pub src2: P::Operand,
+}
+
+pub struct Arg5Setp<P: ArgParams> {
+ pub dst1: P::Id,
+ pub dst2: Option<P::Id>,
+ pub src1: P::Operand,
+ pub src2: P::Operand,
+ pub src3: P::Operand,
+}
+
+#[derive(Copy, Clone)]
+pub enum ImmediateValue {
+ U64(u64),
+ S64(i64),
+ F32(f32),
+ F64(f64),
+}
+
+#[derive(Clone)]
+pub enum Operand<Id> {
+ Reg(Id),
+ RegOffset(Id, i32),
+ Imm(ImmediateValue),
+ VecMember(Id, u8),
+ VecPack(Vec<Id>),
+}
+
+pub enum VectorPrefix {
+ V2,
+ V4,
+}
+
+pub struct LdDetails {
+ pub qualifier: LdStQualifier,
+ pub state_space: LdStateSpace,
+ pub caching: LdCacheOperator,
+ pub typ: LdStType,
+}
+
+sub_type! {
+ LdStType {
+ Scalar(LdStScalarType),
+ Vector(LdStScalarType, u8),
+ // Used in generated code
+ Pointer(PointerType, LdStateSpace),
+ }
+}
+
+impl From<LdStType> for PointerType {
+ fn from(t: LdStType) -> Self {
+ match t {
+ LdStType::Scalar(t) => PointerType::Scalar(t.into()),
+ LdStType::Vector(t, len) => PointerType::Vector(t.into(), len),
+ LdStType::Pointer(PointerType::Scalar(scalar_type), space) => {
+ PointerType::Pointer(scalar_type, space)
+ }
+ LdStType::Pointer(..) => unreachable!(),
+ }
+ }
+}
+
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub enum LdStQualifier {
+ Weak,
+ Volatile,
+ Relaxed(MemScope),
+ Acquire(MemScope),
+}
+
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub enum MemScope {
+ Cta,
+ Gpu,
+ Sys,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+#[repr(u8)]
+pub enum LdStateSpace {
+ Generic,
+ Const,
+ Global,
+ Local,
+ Param,
+ Shared,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub enum LdCacheOperator {
+ Cached,
+ L2Only,
+ Streaming,
+ LastUse,
+ Uncached,
+}
+
+#[derive(Clone)]
+pub struct MovDetails {
+ pub typ: Type,
+ pub src_is_address: bool,
+ // two fields below are in use by member moves
+ pub dst_width: u8,
+ pub src_width: u8,
+ // This is in use by auto-generated movs
+ pub relaxed_src2_conv: bool,
+}
+
+impl MovDetails {
+ pub fn new(typ: Type) -> Self {
+ MovDetails {
+ typ,
+ src_is_address: false,
+ dst_width: 0,
+ src_width: 0,
+ relaxed_src2_conv: false,
+ }
+ }
+}
+
+#[derive(Copy, Clone)]
+pub struct MulIntDesc {
+ pub typ: IntType,
+ pub control: MulIntControl,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub enum MulIntControl {
+ Low,
+ High,
+ Wide,
+}
+
+#[derive(PartialEq, Eq, Copy, Clone)]
+pub enum RoundingMode {
+ NearestEven,
+ Zero,
+ NegativeInf,
+ PositiveInf,
+}
+
+pub struct AddIntDesc {
+ pub typ: IntType,
+ pub saturate: bool,
+}
+
+pub struct SetpData {
+ pub typ: ScalarType,
+ pub flush_to_zero: Option<bool>,
+ pub cmp_op: SetpCompareOp,
+}
+
+#[derive(PartialEq, Eq, Copy, Clone)]
+pub enum SetpCompareOp {
+ Eq,
+ NotEq,
+ Less,
+ LessOrEq,
+ Greater,
+ GreaterOrEq,
+ NanEq,
+ NanNotEq,
+ NanLess,
+ NanLessOrEq,
+ NanGreater,
+ NanGreaterOrEq,
+ IsNotNan,
+ IsNan,
+}
+
+pub enum SetpBoolPostOp {
+ And,
+ Or,
+ Xor,
+}
+
+pub struct SetpBoolData {
+ pub typ: ScalarType,
+ pub flush_to_zero: Option<bool>,
+ pub cmp_op: SetpCompareOp,
+ pub bool_op: SetpBoolPostOp,
+}
+
+pub struct BraData {
+ pub uniform: bool,
+}
+
+pub enum CvtDetails {
+ IntFromInt(CvtIntToIntDesc),
+ FloatFromFloat(CvtDesc<FloatType, FloatType>),
+ IntFromFloat(CvtDesc<IntType, FloatType>),
+ FloatFromInt(CvtDesc<FloatType, IntType>),
+}
+
+pub struct CvtIntToIntDesc {
+ pub dst: IntType,
+ pub src: IntType,
+ pub saturate: bool,
+}
+
+pub struct CvtDesc<Dst, Src> {
+ pub rounding: Option<RoundingMode>,
+ pub flush_to_zero: Option<bool>,
+ pub saturate: bool,
+ pub dst: Dst,
+ pub src: Src,
+}
+
+impl CvtDetails {
+ pub fn new_int_from_int_checked(
+ saturate: bool,
+ dst: IntType,
+ src: IntType,
+ err: &mut Vec<PtxError>,
+ ) -> Self {
+ if saturate {
+ if src.is_signed() {
+ if dst.is_signed() && dst.width() >= src.width() {
+ err.push(PtxError::SyntaxError);
+ }
+ } else {
+ if dst == src || dst.width() >= src.width() {
+ err.push(PtxError::SyntaxError);
+ }
+ }
+ }
+ CvtDetails::IntFromInt(CvtIntToIntDesc { dst, src, saturate })
+ }
+
+ pub fn new_float_from_int_checked(
+ rounding: RoundingMode,
+ flush_to_zero: bool,
+ saturate: bool,
+ dst: FloatType,
+ src: IntType,
+ err: &mut Vec<PtxError>,
+ ) -> Self {
+ if flush_to_zero && dst != FloatType::F32 {
+ err.push(PtxError::NonF32Ftz);
+ }
+ CvtDetails::FloatFromInt(CvtDesc {
+ dst,
+ src,
+ saturate,
+ flush_to_zero: Some(flush_to_zero),
+ rounding: Some(rounding),
+ })
+ }
+
+ pub fn new_int_from_float_checked(
+ rounding: RoundingMode,
+ flush_to_zero: bool,
+ saturate: bool,
+ dst: IntType,
+ src: FloatType,
+ err: &mut Vec<PtxError>,
+ ) -> Self {
+ if flush_to_zero && src != FloatType::F32 {
+ err.push(PtxError::NonF32Ftz);
+ }
+ CvtDetails::IntFromFloat(CvtDesc {
+ dst,
+ src,
+ saturate,
+ flush_to_zero: Some(flush_to_zero),
+ rounding: Some(rounding),
+ })
+ }
+}
+
+pub struct CvtaDetails {
+ pub to: CvtaStateSpace,
+ pub from: CvtaStateSpace,
+ pub size: CvtaSize,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub enum CvtaStateSpace {
+ Generic,
+ Const,
+ Global,
+ Local,
+ Shared,
+}
+
+pub enum CvtaSize {
+ U32,
+ U64,
+}
+
+#[derive(PartialEq, Eq, Copy, Clone)]
+pub enum ShlType {
+ B16,
+ B32,
+ B64,
+}
+
+sub_enum!(ShrType {
+ B16,
+ B32,
+ B64,
+ U16,
+ U32,
+ U64,
+ S16,
+ S32,
+ S64,
+});
+
+pub struct StData {
+ pub qualifier: LdStQualifier,
+ pub state_space: StStateSpace,
+ pub caching: StCacheOperator,
+ pub typ: LdStType,
+}
+
+#[derive(PartialEq, Eq, Copy, Clone)]
+pub enum StStateSpace {
+ Generic,
+ Global,
+ Local,
+ Param,
+ Shared,
+}
+
+#[derive(PartialEq, Eq)]
+pub enum StCacheOperator {
+ Writeback,
+ L2Only,
+ Streaming,
+ Writethrough,
+}
+
+pub struct RetData {
+ pub uniform: bool,
+}
+
+sub_enum!(BooleanType {
+ Pred,
+ B16,
+ B32,
+ B64,
+});
+
+#[derive(Copy, Clone)]
+pub enum MulDetails {
+ Unsigned(MulUInt),
+ Signed(MulSInt),
+ Float(ArithFloat),
+}
+
+#[derive(Copy, Clone)]
+pub struct MulUInt {
+ pub typ: UIntType,
+ pub control: MulIntControl,
+}
+
+#[derive(Copy, Clone)]
+pub struct MulSInt {
+ pub typ: SIntType,
+ pub control: MulIntControl,
+}
+
+#[derive(Copy, Clone)]
+pub enum ArithDetails {
+ Unsigned(UIntType),
+ Signed(ArithSInt),
+ Float(ArithFloat),
+}
+
+#[derive(Copy, Clone)]
+pub struct ArithSInt {
+ pub typ: SIntType,
+ pub saturate: bool,
+}
+
+#[derive(Copy, Clone)]
+pub struct ArithFloat {
+ pub typ: FloatType,
+ pub rounding: Option<RoundingMode>,
+ pub flush_to_zero: Option<bool>,
+ pub saturate: bool,
+}
+
+#[derive(Copy, Clone)]
+pub enum MinMaxDetails {
+ Signed(SIntType),
+ Unsigned(UIntType),
+ Float(MinMaxFloat),
+}
+
+#[derive(Copy, Clone)]
+pub struct MinMaxFloat {
+ pub flush_to_zero: Option<bool>,
+ pub nan: bool,
+ pub typ: FloatType,
+}
+
+#[derive(Copy, Clone)]
+pub struct AtomDetails {
+ pub semantics: AtomSemantics,
+ pub scope: MemScope,
+ pub space: AtomSpace,
+ pub inner: AtomInnerDetails,
+}
+
+#[derive(Copy, Clone)]
+pub enum AtomSemantics {
+ Relaxed,
+ Acquire,
+ Release,
+ AcquireRelease,
+}
+
+#[derive(Copy, Clone)]
+pub enum AtomSpace {
+ Generic,
+ Global,
+ Shared,
+}
+
+#[derive(Copy, Clone)]
+pub enum AtomInnerDetails {
+ Bit { op: AtomBitOp, typ: BitType },
+ Unsigned { op: AtomUIntOp, typ: UIntType },
+ Signed { op: AtomSIntOp, typ: SIntType },
+ Float { op: AtomFloatOp, typ: FloatType },
+}
+
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub enum AtomBitOp {
+ And,
+ Or,
+ Xor,
+ Exchange,
+}
+
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub enum AtomUIntOp {
+ Add,
+ Inc,
+ Dec,
+ Min,
+ Max,
+}
+
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub enum AtomSIntOp {
+ Add,
+ Min,
+ Max,
+}
+
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub enum AtomFloatOp {
+ Add,
+}
+
+#[derive(Copy, Clone)]
+pub struct AtomCasDetails {
+ pub semantics: AtomSemantics,
+ pub scope: MemScope,
+ pub space: AtomSpace,
+ pub typ: BitType,
+}
+
+#[derive(Copy, Clone)]
+pub enum DivDetails {
+ Unsigned(UIntType),
+ Signed(SIntType),
+ Float(DivFloatDetails),
+}
+
+#[derive(Copy, Clone)]
+pub struct DivFloatDetails {
+ pub typ: FloatType,
+ pub flush_to_zero: Option<bool>,
+ pub kind: DivFloatKind,
+}
+
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub enum DivFloatKind {
+ Approx,
+ Full,
+ Rounding(RoundingMode),
+}
+
+pub enum NumsOrArrays<'a> {
+ Nums(Vec<(&'a str, u32)>),
+ Arrays(Vec<NumsOrArrays<'a>>),
+}
+
+#[derive(Copy, Clone)]
+pub struct SqrtDetails {
+ pub typ: FloatType,
+ pub flush_to_zero: Option<bool>,
+ pub kind: SqrtKind,
+}
+
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub enum SqrtKind {
+ Approx,
+ Rounding(RoundingMode),
+}
+
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub struct RsqrtDetails {
+ pub typ: FloatType,
+ pub flush_to_zero: bool,
+}
+
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub struct NegDetails {
+ pub typ: ScalarType,
+ pub flush_to_zero: Option<bool>,
+}
+
+impl<'a> NumsOrArrays<'a> {
+ pub fn to_vec(self, typ: SizedScalarType, dimensions: &mut [u32]) -> Result<Vec<u8>, PtxError> {
+ self.normalize_dimensions(dimensions)?;
+ let sizeof_t = ScalarType::from(typ).size_of() as usize;
+ let result_size = dimensions.iter().fold(sizeof_t, |x, y| x * (*y as usize));
+ let mut result = vec![0; result_size];
+ self.parse_and_copy(typ, sizeof_t, dimensions, &mut result)?;
+ Ok(result)
+ }
+
+ fn normalize_dimensions(&self, dimensions: &mut [u32]) -> Result<(), PtxError> {
+ match dimensions.first_mut() {
+ Some(first) => {
+ if *first == 0 {
+ *first = match self {
+ NumsOrArrays::Nums(v) => v.len() as u32,
+ NumsOrArrays::Arrays(v) => v.len() as u32,
+ };
+ }
+ }
+ None => return Err(PtxError::ZeroDimensionArray),
+ }
+ for dim in dimensions {
+ if *dim == 0 {
+ return Err(PtxError::ZeroDimensionArray);
+ }
+ }
+ Ok(())
+ }
+
+ fn parse_and_copy(
+ &self,
+ t: SizedScalarType,
+ size_of_t: usize,
+ dimensions: &[u32],
+ result: &mut [u8],
+ ) -> Result<(), PtxError> {
+ match dimensions {
+ [] => unreachable!(),
+ [dim] => match self {
+ NumsOrArrays::Nums(vec) => {
+ if vec.len() > *dim as usize {
+ return Err(PtxError::ZeroDimensionArray);
+ }
+ for (idx, (val, radix)) in vec.iter().enumerate() {
+ Self::parse_and_copy_single(t, idx, val, *radix, result)?;
+ }
+ }
+ NumsOrArrays::Arrays(_) => return Err(PtxError::ZeroDimensionArray),
+ },
+ [first_dim, rest @ ..] => match self {
+ NumsOrArrays::Arrays(vec) => {
+ if vec.len() > *first_dim as usize {
+ return Err(PtxError::ZeroDimensionArray);
+ }
+ let size_of_element = rest.iter().fold(size_of_t, |x, y| x * (*y as usize));
+ for (idx, this) in vec.iter().enumerate() {
+ this.parse_and_copy(
+ t,
+ size_of_t,
+ rest,
+ &mut result[(size_of_element * idx)..],
+ )?;
+ }
+ }
+ NumsOrArrays::Nums(_) => return Err(PtxError::ZeroDimensionArray),
+ },
+ }
+ Ok(())
+ }
+
+ fn parse_and_copy_single(
+ t: SizedScalarType,
+ idx: usize,
+ str_val: &str,
+ radix: u32,
+ output: &mut [u8],
+ ) -> Result<(), PtxError> {
+ match t {
+ SizedScalarType::B8 | SizedScalarType::U8 => {
+ Self::parse_and_copy_single_t::<u8>(idx, str_val, radix, output)?;
+ }
+ SizedScalarType::B16 | SizedScalarType::U16 => {
+ Self::parse_and_copy_single_t::<u16>(idx, str_val, radix, output)?;
+ }
+ SizedScalarType::B32 | SizedScalarType::U32 => {
+ Self::parse_and_copy_single_t::<u32>(idx, str_val, radix, output)?;
+ }
+ SizedScalarType::B64 | SizedScalarType::U64 => {
+ Self::parse_and_copy_single_t::<u64>(idx, str_val, radix, output)?;
+ }
+ SizedScalarType::S8 => {
+ Self::parse_and_copy_single_t::<i8>(idx, str_val, radix, output)?;
+ }
+ SizedScalarType::S16 => {
+ Self::parse_and_copy_single_t::<i16>(idx, str_val, radix, output)?;
+ }
+ SizedScalarType::S32 => {
+ Self::parse_and_copy_single_t::<i32>(idx, str_val, radix, output)?;
+ }
+ SizedScalarType::S64 => {
+ Self::parse_and_copy_single_t::<i64>(idx, str_val, radix, output)?;
+ }
+ SizedScalarType::F16 => {
+ Self::parse_and_copy_single_t::<f16>(idx, str_val, radix, output)?;
+ }
+ SizedScalarType::F16x2 => todo!(),
+ SizedScalarType::F32 => {
+ Self::parse_and_copy_single_t::<f32>(idx, str_val, radix, output)?;
+ }
+ SizedScalarType::F64 => {
+ Self::parse_and_copy_single_t::<f64>(idx, str_val, radix, output)?;
+ }
+ }
+ Ok(())
+ }
+
+ fn parse_and_copy_single_t<T: Copy + FromStr>(
+ idx: usize,
+ str_val: &str,
+ _radix: u32, // TODO: use this to properly support hex literals
+ output: &mut [u8],
+ ) -> Result<(), PtxError>
+ where
+ T::Err: Into<PtxError>,
+ {
+ let typed_output = unsafe {
+ std::slice::from_raw_parts_mut::<T>(
+ output.as_mut_ptr() as *mut _,
+ output.len() / mem::size_of::<T>(),
+ )
+ };
+ typed_output[idx] = str_val.parse::<T>().map_err(|e| e.into())?;
+ Ok(())
+ }
+}
+
+pub enum ArrayOrPointer {
+ Array { dimensions: Vec<u32>, init: Vec<u8> },
+ Pointer,
+}
+
+bitflags! {
+ pub struct LinkingDirective: u8 {
+ const NONE = 0b000;
+ const EXTERN = 0b001;
+ const VISIBLE = 0b10;
+ const WEAK = 0b100;
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn array_fails_multiple_0_dmiensions() {
+ let inp = NumsOrArrays::Nums(Vec::new());
+ assert!(inp.to_vec(SizedScalarType::B8, &mut vec![0, 0]).is_err());
+ }
+
+ #[test]
+ fn array_fails_on_empty() {
+ let inp = NumsOrArrays::Nums(Vec::new());
+ assert!(inp.to_vec(SizedScalarType::B8, &mut vec![0]).is_err());
+ }
+
+ #[test]
+ fn array_auto_sizes_0_dimension() {
+ let inp = NumsOrArrays::Arrays(vec![
+ NumsOrArrays::Nums(vec![("1", 10), ("2", 10)]),
+ NumsOrArrays::Nums(vec![("3", 10), ("4", 10)]),
+ ]);
+ let mut dimensions = vec![0u32, 2];
+ assert_eq!(
+ vec![1u8, 2, 3, 4],
+ inp.to_vec(SizedScalarType::B8, &mut dimensions).unwrap()
+ );
+ assert_eq!(dimensions, vec![2u32, 2]);
+ }
+
+ #[test]
+ fn array_fails_wrong_structure() {
+ let inp = NumsOrArrays::Arrays(vec![
+ NumsOrArrays::Nums(vec![("1", 10), ("2", 10)]),
+ NumsOrArrays::Arrays(vec![NumsOrArrays::Nums(vec![("1", 10)])]),
+ ]);
+ let mut dimensions = vec![0u32, 2];
+ assert!(inp.to_vec(SizedScalarType::B8, &mut dimensions).is_err());
+ }
+
+ #[test]
+ fn array_fails_too_long_component() {
+ let inp = NumsOrArrays::Arrays(vec![
+ NumsOrArrays::Nums(vec![("1", 10), ("2", 10), ("3", 10)]),
+ NumsOrArrays::Nums(vec![("4", 10), ("5", 10)]),
+ ]);
+ let mut dimensions = vec![0u32, 2];
+ assert!(inp.to_vec(SizedScalarType::B8, &mut dimensions).is_err());
+ }
+}
diff --git a/ptx/src/lib.rs b/ptx/src/lib.rs
new file mode 100644
index 0000000..591428f
--- /dev/null
+++ b/ptx/src/lib.rs
@@ -0,0 +1,57 @@
+#[cfg(test)]
+extern crate paste;
+#[macro_use]
+extern crate lalrpop_util;
+#[macro_use]
+extern crate quick_error;
+
+extern crate bit_vec;
+extern crate half;
+#[cfg(test)]
+extern crate level_zero as ze;
+#[cfg(test)]
+extern crate level_zero_sys as l0;
+extern crate rspirv;
+extern crate spirv_headers as spirv;
+
+#[cfg(test)]
+extern crate spirv_tools_sys as spirv_tools;
+
+#[macro_use]
+extern crate bitflags;
+
+lalrpop_mod!(
+ #[allow(warnings)]
+ ptx
+);
+
+pub mod ast;
+#[cfg(test)]
+mod test;
+mod translate;
+
+pub use crate::ptx::ModuleParser;
+pub use lalrpop_util::lexer::Token;
+pub use lalrpop_util::ParseError;
+pub use rspirv::dr::Error as SpirvError;
+pub use translate::to_spirv_module;
+pub use translate::KernelInfo;
+pub use translate::TranslateError;
+
+pub(crate) fn without_none<T>(x: Vec<Option<T>>) -> Vec<T> {
+ x.into_iter().filter_map(|x| x).collect()
+}
+
+pub(crate) fn vector_index<'input>(
+ inp: &'input str,
+) -> Result<u8, ParseError<usize, lalrpop_util::lexer::Token<'input>, ast::PtxError>> {
+ match inp {
+ "x" | "r" => Ok(0),
+ "y" | "g" => Ok(1),
+ "z" | "b" => Ok(2),
+ "w" | "a" => Ok(3),
+ _ => Err(ParseError::User {
+ error: ast::PtxError::WrongVectorElement,
+ }),
+ }
+}
diff --git a/ptx/src/ptx.lalrpop b/ptx/src/ptx.lalrpop
new file mode 100644
index 0000000..fd2a3f1
--- /dev/null
+++ b/ptx/src/ptx.lalrpop
@@ -0,0 +1,2004 @@
+use crate::ast;
+use crate::ast::UnwrapWithVec;
+use crate::{without_none, vector_index};
+
+use lalrpop_util::ParseError;
+use std::convert::TryInto;
+
+grammar<'a>(errors: &mut Vec<ast::PtxError>);
+
+extern {
+ type Error = ast::PtxError;
+}
+
+match {
+ r"\s+" => { },
+ r"//[^\n\r]*[\n\r]*" => { },
+ r"/\*([^\*]*\*+[^\*/])*([^\*]*\*+|[^\*])*\*/" => { },
+ r"0[fF][0-9a-zA-Z]{8}" => F32NumToken,
+ r"0[dD][0-9a-zA-Z]{16}" => F64NumToken,
+ r"0[xX][0-9a-zA-Z]+U?" => HexNumToken,
+ r"[0-9]+U?" => DecimalNumToken,
+ r#""[^"]*""# => String,
+ r"[0-9]+\.[0-9]+" => VersionNumber,
+ "!",
+ "(", ")",
+ "+",
+ "-",
+ ",",
+ ".",
+ ":",
+ ";",
+ "@",
+ "[", "]",
+ "{", "}",
+ "<", ">",
+ "|",
+ "=",
+ ".acq_rel",
+ ".acquire",
+ ".add",
+ ".address_size",
+ ".align",
+ ".aligned",
+ ".and",
+ ".approx",
+ ".b16",
+ ".b32",
+ ".b64",
+ ".b8",
+ ".ca",
+ ".cas",
+ ".cg",
+ ".const",
+ ".cs",
+ ".cta",
+ ".cv",
+ ".dec",
+ ".entry",
+ ".eq",
+ ".equ",
+ ".exch",
+ ".extern",
+ ".f16",
+ ".f16x2",
+ ".f32",
+ ".f64",
+ ".file",
+ ".ftz",
+ ".full",
+ ".func",
+ ".ge",
+ ".geu",
+ ".global",
+ ".gpu",
+ ".gt",
+ ".gtu",
+ ".hi",
+ ".hs",
+ ".inc",
+ ".le",
+ ".leu",
+ ".lo",
+ ".loc",
+ ".local",
+ ".ls",
+ ".lt",
+ ".ltu",
+ ".lu",
+ ".max",
+ ".min",
+ ".nan",
+ ".NaN",
+ ".ne",
+ ".neu",
+ ".num",
+ ".or",
+ ".param",
+ ".pragma",
+ ".pred",
+ ".reg",
+ ".relaxed",
+ ".release",
+ ".rm",
+ ".rmi",
+ ".rn",
+ ".rni",
+ ".rp",
+ ".rpi",
+ ".rz",
+ ".rzi",
+ ".s16",
+ ".s32",
+ ".s64",
+ ".s8" ,
+ ".sat",
+ ".section",
+ ".shared",
+ ".sync",
+ ".sys",
+ ".target",
+ ".to",
+ ".u16",
+ ".u32",
+ ".u64",
+ ".u8" ,
+ ".uni",
+ ".v2",
+ ".v4",
+ ".version",
+ ".visible",
+ ".volatile",
+ ".wb",
+ ".weak",
+ ".wide",
+ ".wt",
+ ".xor",
+} else {
+ // IF YOU ARE ADDING A NEW TOKEN HERE ALSO ADD IT BELOW TO ExtendedID
+ "abs",
+ "add",
+ "and",
+ "atom",
+ "bar",
+ "barrier",
+ "bfe",
+ "bra",
+ "brev",
+ "call",
+ "clz",
+ "cos",
+ "cvt",
+ "cvta",
+ "debug",
+ "div",
+ "ex2",
+ "fma",
+ "ld",
+ "lg2",
+ "mad",
+ "map_f64_to_f32",
+ "max",
+ "min",
+ "mov",
+ "mul",
+ "neg",
+ "not",
+ "or",
+ "popc",
+ "rcp",
+ "rem",
+ "ret",
+ "rsqrt",
+ "selp",
+ "setp",
+ "shl",
+ "shr",
+ "sin",
+ r"sm_[0-9]+" => ShaderModel,
+ "sqrt",
+ "st",
+ "sub",
+ "texmode_independent",
+ "texmode_unified",
+ "xor",
+} else {
+ // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#identifiers
+ r"[a-zA-Z][a-zA-Z0-9_$]*|[_$%][a-zA-Z0-9_$]+" => ID,
+ r"\.[a-zA-Z][a-zA-Z0-9_$]*" => DotID,
+}
+
+ExtendedID : &'input str = {
+ "abs",
+ "add",
+ "and",
+ "atom",
+ "bar",
+ "barrier",
+ "bfe",
+ "bra",
+ "brev",
+ "call",
+ "clz",
+ "cos",
+ "cvt",
+ "cvta",
+ "debug",
+ "div",
+ "ex2",
+ "fma",
+ "ld",
+ "lg2",
+ "mad",
+ "map_f64_to_f32",
+ "max",
+ "min",
+ "mov",
+ "mul",
+ "neg",
+ "not",
+ "or",
+ "popc",
+ "rcp",
+ "rem",
+ "ret",
+ "rsqrt",
+ "selp",
+ "setp",
+ "shl",
+ "shr",
+ "sin",
+ ShaderModel,
+ "sqrt",
+ "st",
+ "sub",
+ "texmode_independent",
+ "texmode_unified",
+ "xor",
+ ID
+}
+
+NumToken: (&'input str, u32, bool) = {
+ <s:HexNumToken> => {
+ if s.ends_with('U') {
+ (&s[2..s.len() - 1], 16, true)
+ } else {
+ (&s[2..], 16, false)
+ }
+ },
+ <s:DecimalNumToken> => {
+ let radix = if s.starts_with('0') { 8 } else { 10 };
+ if s.ends_with('U') {
+ (&s[..s.len() - 1], radix, true)
+ } else {
+ (s, radix, false)
+ }
+ }
+}
+
+F32Num: f32 = {
+ <s:F32NumToken> =>? {
+ match u32::from_str_radix(&s[2..], 16) {
+ Ok(x) => Ok(unsafe { std::mem::transmute::<_, f32>(x) }),
+ Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) })
+ }
+
+ }
+}
+
+F64Num: f64 = {
+ <s:F64NumToken> =>? {
+ match u64::from_str_radix(&s[2..], 16) {
+ Ok(x) => Ok(unsafe { std::mem::transmute::<_, f64>(x) }),
+ Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) })
+ }
+ }
+}
+
+U8Num: u8 = {
+ <x:NumToken> =>? {
+ let (text, radix, _) = x;
+ match u8::from_str_radix(text, radix) {
+ Ok(x) => Ok(x),
+ Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) })
+ }
+ }
+}
+
+U32Num: u32 = {
+ <x:NumToken> =>? {
+ let (text, radix, _) = x;
+ match u32::from_str_radix(text, radix) {
+ Ok(x) => Ok(x),
+ Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) })
+ }
+ }
+}
+
+// TODO: handle negative number properly
+S32Num: i32 = {
+ <sign:"-"?> <x:NumToken> =>? {
+ let (text, radix, _) = x;
+ match i32::from_str_radix(text, radix) {
+ Ok(x) => Ok(if sign.is_some() { -x } else { x }),
+ Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) })
+ }
+ }
+}
+
+pub Module: ast::Module<'input> = {
+ <v:Version> Target <d:Directive*> => {
+ ast::Module { version: v, directives: without_none(d) }
+ }
+};
+
+Version: (u8, u8) = {
+ ".version" <v:VersionNumber> => {
+ let dot = v.find('.').unwrap();
+ let major = v[..dot].parse::<u8>();
+ let minor = v[dot+1..].parse::<u8>();
+ (major,minor).unwrap_with(errors)
+ }
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#ptx-module-directives-target
+Target = {
+ ".target" Comma<TargetSpecifier>
+};
+
+TargetSpecifier = {
+ ShaderModel,
+ "texmode_unified",
+ "texmode_independent",
+ "debug",
+ "map_f64_to_f32"
+};
+
+Directive: Option<ast::Directive<'input, ast::ParsedArgParams<'input>>> = {
+ AddressSize => None,
+ <f:Function> => Some(ast::Directive::Method(f)),
+ File => None,
+ Section => None,
+ <v:ModuleVariable> ";" => Some(ast::Directive::Variable(v)),
+};
+
+AddressSize = {
+ ".address_size" U8Num
+};
+
+Function: ast::Function<'input, &'input str, ast::Statement<ast::ParsedArgParams<'input>>> = {
+ LinkingDirectives
+ <func_directive:MethodDecl>
+ <body:FunctionBody> => ast::Function{<>}
+};
+
+LinkingDirective: ast::LinkingDirective = {
+ ".extern" => ast::LinkingDirective::EXTERN,
+ ".visible" => ast::LinkingDirective::VISIBLE,
+ ".weak" => ast::LinkingDirective::WEAK,
+};
+
+LinkingDirectives: ast::LinkingDirective = {
+ <ldirs:LinkingDirective*> => {
+ ldirs.into_iter().fold(ast::LinkingDirective::NONE, |x, y| x | y)
+ }
+}
+
+MethodDecl: ast::MethodDecl<'input, &'input str> = {
+ ".entry" <name:ExtendedID> <in_args:KernelArguments> =>
+ ast::MethodDecl::Kernel{ name, in_args },
+ ".func" <ret_vals:FnArguments?> <name:ExtendedID> <params:FnArguments> => {
+ ast::MethodDecl::Func(ret_vals.unwrap_or_else(|| Vec::new()), name, params)
+ }
+};
+
+KernelArguments: Vec<ast::KernelArgument<&'input str>> = {
+ "(" <args:Comma<KernelInput>> ")" => args
+};
+
+FnArguments: Vec<ast::FnArgument<&'input str>> = {
+ "(" <args:Comma<FnInput>> ")" => args
+};
+
+KernelInput: ast::Variable<ast::KernelArgumentType, &'input str> = {
+ <v:ParamDeclaration> => {
+ let (align, v_type, name) = v;
+ ast::Variable {
+ align,
+ v_type: ast::KernelArgumentType::Normal(v_type),
+ name,
+ array_init: Vec::new()
+ }
+ }
+}
+
+FnInput: ast::Variable<ast::FnArgumentType, &'input str> = {
+ <v:RegVariable> => {
+ let (align, v_type, name) = v;
+ let v_type = ast::FnArgumentType::Reg(v_type);
+ ast::Variable{ align, v_type, name, array_init: Vec::new() }
+ },
+ <v:ParamDeclaration> => {
+ let (align, v_type, name) = v;
+ let v_type = ast::FnArgumentType::Param(v_type);
+ ast::Variable{ align, v_type, name, array_init: Vec::new() }
+ }
+}
+
+pub(crate) FunctionBody: Option<Vec<ast::Statement<ast::ParsedArgParams<'input>>>> = {
+ "{" <s:Statement*> "}" => { Some(without_none(s)) },
+ ";" => { None }
+};
+
+StateSpaceSpecifier: ast::StateSpace = {
+ ".reg" => ast::StateSpace::Reg,
+ ".const" => ast::StateSpace::Const,
+ ".global" => ast::StateSpace::Global,
+ ".local" => ast::StateSpace::Local,
+ ".shared" => ast::StateSpace::Shared,
+ ".param" => ast::StateSpace::Param, // used to prepare function call
+};
+
+#[inline]
+ScalarType: ast::ScalarType = {
+ ".f16" => ast::ScalarType::F16,
+ ".f16x2" => ast::ScalarType::F16x2,
+ ".pred" => ast::ScalarType::Pred,
+ ".b8" => ast::ScalarType::B8,
+ ".b16" => ast::ScalarType::B16,
+ ".b32" => ast::ScalarType::B32,
+ ".b64" => ast::ScalarType::B64,
+ ".u8" => ast::ScalarType::U8,
+ ".u16" => ast::ScalarType::U16,
+ ".u32" => ast::ScalarType::U32,
+ ".u64" => ast::ScalarType::U64,
+ ".s8" => ast::ScalarType::S8,
+ ".s16" => ast::ScalarType::S16,
+ ".s32" => ast::ScalarType::S32,
+ ".s64" => ast::ScalarType::S64,
+ ".f32" => ast::ScalarType::F32,
+ ".f64" => ast::ScalarType::F64,
+};
+
+Statement: Option<ast::Statement<ast::ParsedArgParams<'input>>> = {
+ <l:Label> => Some(ast::Statement::Label(l)),
+ DebugDirective => None,
+ <v:MultiVariable> ";" => Some(ast::Statement::Variable(v)),
+ <p:PredAt?> <i:Instruction> ";" => Some(ast::Statement::Instruction(p, i)),
+ PragmaStatement => None,
+ "{" <s:Statement*> "}" => Some(ast::Statement::Block(without_none(s)))
+};
+
+PragmaStatement: () = {
+ ".pragma" String ";"
+}
+
+DebugDirective: () = {
+ DebugLocation
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#debugging-directives-loc
+DebugLocation = {
+ ".loc" U32Num U32Num U32Num
+};
+
+Label: &'input str = {
+ <id:ExtendedID> ":" => id
+};
+
+Align: u32 = {
+ ".align" <x:U32Num> => x
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parameterized-variable-names
+MultiVariable: ast::MultiVariable<&'input str> = {
+ <var:Variable> <count:VariableParam?> => ast::MultiVariable{<>}
+}
+
+VariableParam: u32 = {
+ "<" <n:U32Num> ">" => n
+}
+
+Variable: ast::Variable<ast::VariableType, &'input str> = {
+ <v:RegVariable> => {
+ let (align, v_type, name) = v;
+ let v_type = ast::VariableType::Reg(v_type);
+ ast::Variable {align, v_type, name, array_init: Vec::new()}
+ },
+ LocalVariable,
+ <v:ParamVariable> => {
+ let (align, array_init, v_type, name) = v;
+ let v_type = ast::VariableType::Param(v_type);
+ ast::Variable {align, v_type, name, array_init}
+ },
+ SharedVariable,
+};
+
+RegVariable: (Option<u32>, ast::VariableRegType, &'input str) = {
+ ".reg" <var:VariableScalar<ScalarType>> => {
+ let (align, t, name) = var;
+ let v_type = ast::VariableRegType::Scalar(t);
+ (align, v_type, name)
+ },
+ ".reg" <var:VariableVector<SizedScalarType>> => {
+ let (align, v_len, t, name) = var;
+ let v_type = ast::VariableRegType::Vector(t, v_len);
+ (align, v_type, name)
+ }
+}
+
+LocalVariable: ast::Variable<ast::VariableType, &'input str> = {
+ ".local" <var:VariableScalar<SizedScalarType>> => {
+ let (align, t, name) = var;
+ let v_type = ast::VariableType::Local(ast::VariableLocalType::Scalar(t));
+ ast::Variable { align, v_type, name, array_init: Vec::new() }
+ },
+ ".local" <var:VariableVector<SizedScalarType>> => {
+ let (align, v_len, t, name) = var;
+ let v_type = ast::VariableType::Local(ast::VariableLocalType::Vector(t, v_len));
+ ast::Variable { align, v_type, name, array_init: Vec::new() }
+ },
+ ".local" <var:VariableArrayOrPointer<SizedScalarType>> =>? {
+ let (align, t, name, arr_or_ptr) = var;
+ let (v_type, array_init) = match arr_or_ptr {
+ ast::ArrayOrPointer::Array { dimensions, init } => {
+ (ast::VariableLocalType::Array(t, dimensions), init)
+ }
+ ast::ArrayOrPointer::Pointer => {
+ return Err(ParseError::User { error: ast::PtxError::ZeroDimensionArray });
+ }
+ };
+ Ok(ast::Variable { align, v_type: ast::VariableType::Local(v_type), name, array_init })
+ }
+}
+
+SharedVariable: ast::Variable<ast::VariableType, &'input str> = {
+ ".shared" <var:VariableScalar<SizedScalarType>> => {
+ let (align, t, name) = var;
+ let v_type = ast::VariableGlobalType::Scalar(t);
+ ast::Variable { align, v_type: ast::VariableType::Shared(v_type), name, array_init: Vec::new() }
+ },
+ ".shared" <var:VariableVector<SizedScalarType>> => {
+ let (align, v_len, t, name) = var;
+ let v_type = ast::VariableGlobalType::Vector(t, v_len);
+ ast::Variable { align, v_type: ast::VariableType::Shared(v_type), name, array_init: Vec::new() }
+ },
+ ".shared" <var:VariableArrayOrPointer<SizedScalarType>> =>? {
+ let (align, t, name, arr_or_ptr) = var;
+ let (v_type, array_init) = match arr_or_ptr {
+ ast::ArrayOrPointer::Array { dimensions, init } => {
+ (ast::VariableGlobalType::Array(t, dimensions), init)
+ }
+ ast::ArrayOrPointer::Pointer => {
+ return Err(ParseError::User { error: ast::PtxError::ZeroDimensionArray });
+ }
+ };
+ Ok(ast::Variable { align, v_type: ast::VariableType::Shared(v_type), name, array_init })
+ }
+}
+
+
+ModuleVariable: ast::Variable<ast::VariableType, &'input str> = {
+ LinkingDirectives ".global" <def:GlobalVariableDefinitionNoArray> => {
+ let (align, v_type, name, array_init) = def;
+ ast::Variable { align, v_type: ast::VariableType::Global(v_type), name, array_init }
+ },
+ LinkingDirectives ".shared" <def:GlobalVariableDefinitionNoArray> => {
+ let (align, v_type, name, array_init) = def;
+ ast::Variable { align, v_type: ast::VariableType::Shared(v_type), name, array_init: Vec::new() }
+ },
+ <ldirs:LinkingDirectives> <space:Or<".global", ".shared">> <var:VariableArrayOrPointer<SizedScalarType>> =>? {
+ let (align, t, name, arr_or_ptr) = var;
+ let (v_type, array_init) = match arr_or_ptr {
+ ast::ArrayOrPointer::Array { dimensions, init } => {
+ if space == ".global" {
+ (ast::VariableType::Global(ast::VariableGlobalType::Array(t, dimensions)), init)
+ } else {
+ (ast::VariableType::Shared(ast::VariableGlobalType::Array(t, dimensions)), init)
+ }
+ }
+ ast::ArrayOrPointer::Pointer => {
+ if !ldirs.contains(ast::LinkingDirective::EXTERN) {
+ return Err(ParseError::User { error: ast::PtxError::NonExternPointer });
+ }
+ if space == ".global" {
+ (ast::VariableType::Global(ast::VariableGlobalType::Pointer(t, ast::PointerStateSpace::Global)), Vec::new())
+ } else {
+ (ast::VariableType::Shared(ast::VariableGlobalType::Pointer(t, ast::PointerStateSpace::Shared)), Vec::new())
+ }
+ }
+ };
+ Ok(ast::Variable{ align, array_init, v_type, name })
+ }
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parameter-state-space
+ParamVariable: (Option<u32>, Vec<u8>, ast::VariableParamType, &'input str) = {
+ ".param" <var:VariableScalar<LdStScalarType>> => {
+ let (align, t, name) = var;
+ let v_type = ast::VariableParamType::Scalar(t);
+ (align, Vec::new(), v_type, name)
+ },
+ ".param" <var:VariableArrayOrPointer<SizedScalarType>> => {
+ let (align, t, name, arr_or_ptr) = var;
+ let (v_type, array_init) = match arr_or_ptr {
+ ast::ArrayOrPointer::Array { dimensions, init } => {
+ (ast::VariableParamType::Array(t, dimensions), init)
+ }
+ ast::ArrayOrPointer::Pointer => {
+ (ast::VariableParamType::Pointer(t, ast::PointerStateSpace::Param), Vec::new())
+ }
+ };
+ (align, array_init, v_type, name)
+ }
+}
+
+ParamDeclaration: (Option<u32>, ast::VariableParamType, &'input str) = {
+ <var:ParamVariable> =>? {
+ let (align, array_init, v_type, name) = var;
+ if array_init.len() > 0 {
+ Err(ParseError::User { error: ast::PtxError::ArrayInitalizer })
+ } else {
+ Ok((align, v_type, name))
+ }
+ }
+}
+
+GlobalVariableDefinitionNoArray: (Option<u32>, ast::VariableGlobalType, &'input str, Vec<u8>) = {
+ <scalar:VariableScalar<SizedScalarType>> => {
+ let (align, t, name) = scalar;
+ let v_type = ast::VariableGlobalType::Scalar(t);
+ (align, v_type, name, Vec::new())
+ },
+ <var:VariableVector<SizedScalarType>> => {
+ let (align, v_len, t, name) = var;
+ let v_type = ast::VariableGlobalType::Vector(t, v_len);
+ (align, v_type, name, Vec::new())
+ },
+}
+
+#[inline]
+SizedScalarType: ast::SizedScalarType = {
+ ".b8" => ast::SizedScalarType::B8,
+ ".b16" => ast::SizedScalarType::B16,
+ ".b32" => ast::SizedScalarType::B32,
+ ".b64" => ast::SizedScalarType::B64,
+ ".u8" => ast::SizedScalarType::U8,
+ ".u16" => ast::SizedScalarType::U16,
+ ".u32" => ast::SizedScalarType::U32,
+ ".u64" => ast::SizedScalarType::U64,
+ ".s8" => ast::SizedScalarType::S8,
+ ".s16" => ast::SizedScalarType::S16,
+ ".s32" => ast::SizedScalarType::S32,
+ ".s64" => ast::SizedScalarType::S64,
+ ".f16" => ast::SizedScalarType::F16,
+ ".f16x2" => ast::SizedScalarType::F16x2,
+ ".f32" => ast::SizedScalarType::F32,
+ ".f64" => ast::SizedScalarType::F64,
+}
+
+#[inline]
+LdStScalarType: ast::LdStScalarType = {
+ ".b8" => ast::LdStScalarType::B8,
+ ".b16" => ast::LdStScalarType::B16,
+ ".b32" => ast::LdStScalarType::B32,
+ ".b64" => ast::LdStScalarType::B64,
+ ".u8" => ast::LdStScalarType::U8,
+ ".u16" => ast::LdStScalarType::U16,
+ ".u32" => ast::LdStScalarType::U32,
+ ".u64" => ast::LdStScalarType::U64,
+ ".s8" => ast::LdStScalarType::S8,
+ ".s16" => ast::LdStScalarType::S16,
+ ".s32" => ast::LdStScalarType::S32,
+ ".s64" => ast::LdStScalarType::S64,
+ ".f16" => ast::LdStScalarType::F16,
+ ".f32" => ast::LdStScalarType::F32,
+ ".f64" => ast::LdStScalarType::F64,
+}
+
+Instruction: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ InstLd,
+ InstMov,
+ InstMul,
+ InstAdd,
+ InstSetp,
+ InstNot,
+ InstBra,
+ InstCvt,
+ InstShl,
+ InstShr,
+ InstSt,
+ InstRet,
+ InstCvta,
+ InstCall,
+ InstAbs,
+ InstMad,
+ InstOr,
+ InstAnd,
+ InstSub,
+ InstMin,
+ InstMax,
+ InstRcp,
+ InstSelp,
+ InstBar,
+ InstAtom,
+ InstAtomCas,
+ InstDiv,
+ InstSqrt,
+ InstRsqrt,
+ InstNeg,
+ InstSin,
+ InstCos,
+ InstLg2,
+ InstEx2,
+ InstClz,
+ InstBrev,
+ InstPopc,
+ InstXor,
+ InstRem,
+ InstBfe,
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-ld
+InstLd: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "ld" <q:LdStQualifier?> <ss:LdStateSpace?> <cop:LdCacheOperator?> <t:LdStType> <dst:DstOperandVec> "," <src:MemoryOperand> => {
+ ast::Instruction::Ld(
+ ast::LdDetails {
+ qualifier: q.unwrap_or(ast::LdStQualifier::Weak),
+ state_space: ss.unwrap_or(ast::LdStateSpace::Generic),
+ caching: cop.unwrap_or(ast::LdCacheOperator::Cached),
+ typ: t
+ },
+ ast::Arg2Ld { dst:dst, src:src }
+ )
+ }
+};
+
+LdStType: ast::LdStType = {
+ <v:VectorPrefix> <t:LdStScalarType> => ast::LdStType::Vector(t, v),
+ <t:LdStScalarType> => ast::LdStType::Scalar(t),
+}
+
+LdStQualifier: ast::LdStQualifier = {
+ ".weak" => ast::LdStQualifier::Weak,
+ ".volatile" => ast::LdStQualifier::Volatile,
+ ".relaxed" <s:MemScope> => ast::LdStQualifier::Relaxed(s),
+ ".acquire" <s:MemScope> => ast::LdStQualifier::Acquire(s),
+};
+
+MemScope: ast::MemScope = {
+ ".cta" => ast::MemScope::Cta,
+ ".gpu" => ast::MemScope::Gpu,
+ ".sys" => ast::MemScope::Sys
+};
+
+LdStateSpace: ast::LdStateSpace = {
+ ".const" => ast::LdStateSpace::Const,
+ ".global" => ast::LdStateSpace::Global,
+ ".local" => ast::LdStateSpace::Local,
+ ".param" => ast::LdStateSpace::Param,
+ ".shared" => ast::LdStateSpace::Shared,
+};
+
+LdCacheOperator: ast::LdCacheOperator = {
+ ".ca" => ast::LdCacheOperator::Cached,
+ ".cg" => ast::LdCacheOperator::L2Only,
+ ".cs" => ast::LdCacheOperator::Streaming,
+ ".lu" => ast::LdCacheOperator::LastUse,
+ ".cv" => ast::LdCacheOperator::Uncached,
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-mov
+InstMov: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "mov" <pref:VectorPrefix?> <t:MovScalarType> <dst:DstOperandVec> "," <src:SrcOperandVec> => {
+ let mov_type = match pref {
+ Some(vec_width) => ast::Type::Vector(t, vec_width),
+ None => ast::Type::Scalar(t)
+ };
+ let details = ast::MovDetails::new(mov_type);
+ ast::Instruction::Mov(
+ details,
+ ast::Arg2Mov { dst, src }
+ )
+ }
+}
+
+#[inline]
+MovScalarType: ast::ScalarType = {
+ ".b16" => ast::ScalarType::B16,
+ ".b32" => ast::ScalarType::B32,
+ ".b64" => ast::ScalarType::B64,
+ ".u16" => ast::ScalarType::U16,
+ ".u32" => ast::ScalarType::U32,
+ ".u64" => ast::ScalarType::U64,
+ ".s16" => ast::ScalarType::S16,
+ ".s32" => ast::ScalarType::S32,
+ ".s64" => ast::ScalarType::S64,
+ ".f32" => ast::ScalarType::F32,
+ ".f64" => ast::ScalarType::F64,
+ ".pred" => ast::ScalarType::Pred
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-mul
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-mul
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-floating-point-instructions-mul
+InstMul: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "mul" <d:MulDetails> <a:Arg3> => ast::Instruction::Mul(d, a)
+};
+
+MulDetails: ast::MulDetails = {
+ <ctr:MulIntControl> <t:UIntType> => ast::MulDetails::Unsigned(ast::MulUInt{
+ typ: t,
+ control: ctr
+ }),
+ <ctr:MulIntControl> <t:SIntType> => ast::MulDetails::Signed(ast::MulSInt{
+ typ: t,
+ control: ctr
+ }),
+ <f:ArithFloat> => ast::MulDetails::Float(f)
+};
+
+MulIntControl: ast::MulIntControl = {
+ ".hi" => ast::MulIntControl::High,
+ ".lo" => ast::MulIntControl::Low,
+ ".wide" => ast::MulIntControl::Wide
+};
+
+#[inline]
+RoundingModeFloat : ast::RoundingMode = {
+ ".rn" => ast::RoundingMode::NearestEven,
+ ".rz" => ast::RoundingMode::Zero,
+ ".rm" => ast::RoundingMode::NegativeInf,
+ ".rp" => ast::RoundingMode::PositiveInf,
+};
+
+RoundingModeInt : ast::RoundingMode = {
+ ".rni" => ast::RoundingMode::NearestEven,
+ ".rzi" => ast::RoundingMode::Zero,
+ ".rmi" => ast::RoundingMode::NegativeInf,
+ ".rpi" => ast::RoundingMode::PositiveInf,
+};
+
+IntType : ast::IntType = {
+ ".u16" => ast::IntType::U16,
+ ".u32" => ast::IntType::U32,
+ ".u64" => ast::IntType::U64,
+ ".s16" => ast::IntType::S16,
+ ".s32" => ast::IntType::S32,
+ ".s64" => ast::IntType::S64,
+};
+
+IntType3264: ast::IntType = {
+ ".u32" => ast::IntType::U32,
+ ".u64" => ast::IntType::U64,
+ ".s32" => ast::IntType::S32,
+ ".s64" => ast::IntType::S64,
+}
+
+UIntType: ast::UIntType = {
+ ".u16" => ast::UIntType::U16,
+ ".u32" => ast::UIntType::U32,
+ ".u64" => ast::UIntType::U64,
+};
+
+SIntType: ast::SIntType = {
+ ".s16" => ast::SIntType::S16,
+ ".s32" => ast::SIntType::S32,
+ ".s64" => ast::SIntType::S64,
+};
+
+FloatType: ast::FloatType = {
+ ".f16" => ast::FloatType::F16,
+ ".f16x2" => ast::FloatType::F16x2,
+ ".f32" => ast::FloatType::F32,
+ ".f64" => ast::FloatType::F64,
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-add
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-add
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-floating-point-instructions-add
+InstAdd: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "add" <d:ArithDetails> <a:Arg3> => ast::Instruction::Add(d, a)
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#comparison-and-selection-instructions-setp
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-comparison-instructions-setp
+// TODO: support f16 setp
+InstSetp: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "setp" <d:SetpMode> <a:Arg4Setp> => ast::Instruction::Setp(d, a),
+ "setp" <d:SetpBoolMode> <a:Arg5Setp> => ast::Instruction::SetpBool(d, a),
+};
+
+SetpMode: ast::SetpData = {
+ <cmp_op:SetpCompareOp> <t:SetpTypeNoF32> => ast::SetpData {
+ typ: t,
+ flush_to_zero: None,
+ cmp_op: cmp_op,
+ },
+ <cmp_op:SetpCompareOp> <ftz:".ftz"?> ".f32" => ast::SetpData {
+ typ: ast::ScalarType::F32,
+ flush_to_zero: Some(ftz.is_some()),
+ cmp_op: cmp_op,
+ }
+
+};
+
+SetpBoolMode: ast::SetpBoolData = {
+ <cmp_op:SetpCompareOp> <bool_op:SetpBoolPostOp> <t:SetpTypeNoF32> => ast::SetpBoolData {
+ typ: t,
+ flush_to_zero: None,
+ cmp_op: cmp_op,
+ bool_op: bool_op,
+ },
+ <cmp_op:SetpCompareOp> <bool_op:SetpBoolPostOp> <ftz:".ftz"?> ".f32" => ast::SetpBoolData {
+ typ: ast::ScalarType::F32,
+ flush_to_zero: Some(ftz.is_some()),
+ cmp_op: cmp_op,
+ bool_op: bool_op,
+ }
+};
+
+SetpCompareOp: ast::SetpCompareOp = {
+ ".eq" => ast::SetpCompareOp::Eq,
+ ".ne" => ast::SetpCompareOp::NotEq,
+ ".lt" => ast::SetpCompareOp::Less,
+ ".le" => ast::SetpCompareOp::LessOrEq,
+ ".gt" => ast::SetpCompareOp::Greater,
+ ".ge" => ast::SetpCompareOp::GreaterOrEq,
+ ".lo" => ast::SetpCompareOp::Less,
+ ".ls" => ast::SetpCompareOp::LessOrEq,
+ ".hi" => ast::SetpCompareOp::Greater,
+ ".hs" => ast::SetpCompareOp::GreaterOrEq,
+ ".equ" => ast::SetpCompareOp::NanEq,
+ ".neu" => ast::SetpCompareOp::NanNotEq,
+ ".ltu" => ast::SetpCompareOp::NanLess,
+ ".leu" => ast::SetpCompareOp::NanLessOrEq,
+ ".gtu" => ast::SetpCompareOp::NanGreater,
+ ".geu" => ast::SetpCompareOp::NanGreaterOrEq,
+ ".num" => ast::SetpCompareOp::IsNotNan,
+ ".nan" => ast::SetpCompareOp::IsNan,
+};
+
+SetpBoolPostOp: ast::SetpBoolPostOp = {
+ ".and" => ast::SetpBoolPostOp::And,
+ ".or" => ast::SetpBoolPostOp::Or,
+ ".xor" => ast::SetpBoolPostOp::Xor,
+};
+
+SetpTypeNoF32: ast::ScalarType = {
+ ".b16" => ast::ScalarType::B16,
+ ".b32" => ast::ScalarType::B32,
+ ".b64" => ast::ScalarType::B64,
+ ".u16" => ast::ScalarType::U16,
+ ".u32" => ast::ScalarType::U32,
+ ".u64" => ast::ScalarType::U64,
+ ".s16" => ast::ScalarType::S16,
+ ".s32" => ast::ScalarType::S32,
+ ".s64" => ast::ScalarType::S64,
+ ".f64" => ast::ScalarType::F64,
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-not
+InstNot: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "not" <t:BooleanType> <a:Arg2> => ast::Instruction::Not(t, a)
+};
+
+BooleanType: ast::BooleanType = {
+ ".pred" => ast::BooleanType::Pred,
+ ".b16" => ast::BooleanType::B16,
+ ".b32" => ast::BooleanType::B32,
+ ".b64" => ast::BooleanType::B64,
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-at
+PredAt: ast::PredAt<&'input str> = {
+ "@" <label:ExtendedID> => ast::PredAt { not: false, label:label },
+ "@" "!" <label:ExtendedID> => ast::PredAt { not: true, label:label }
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-bra
+InstBra: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "bra" <u:".uni"?> <a:Arg1> => ast::Instruction::Bra(ast::BraData{ uniform: u.is_some() }, a)
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cvt
+InstCvt: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "cvt" <s:".sat"?> <dst_t:CvtTypeInt> <src_t:CvtTypeInt> <a:Arg2> => {
+ ast::Instruction::Cvt(ast::CvtDetails::new_int_from_int_checked(
+ s.is_some(),
+ dst_t,
+ src_t,
+ errors
+ ),
+ a)
+ },
+ "cvt" <r:RoundingModeFloat> <f:".ftz"?> <s:".sat"?> <dst_t:CvtTypeFloat> <src_t:CvtTypeInt> <a:Arg2> => {
+ ast::Instruction::Cvt(ast::CvtDetails::new_float_from_int_checked(
+ r,
+ f.is_some(),
+ s.is_some(),
+ dst_t,
+ src_t,
+ errors
+ ),
+ a)
+ },
+ "cvt" <r:RoundingModeInt> <f:".ftz"?> <s:".sat"?> <dst_t:CvtTypeInt> <src_t:CvtTypeFloat> <a:Arg2> => {
+ ast::Instruction::Cvt(ast::CvtDetails::new_int_from_float_checked(
+ r,
+ f.is_some(),
+ s.is_some(),
+ dst_t,
+ src_t,
+ errors
+ ),
+ a)
+ },
+ "cvt" <r:RoundingModeInt?> <s:".sat"?> ".f16" ".f16" <a:Arg2> => {
+ ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat(
+ ast::CvtDesc {
+ rounding: r,
+ flush_to_zero: None,
+ saturate: s.is_some(),
+ dst: ast::FloatType::F16,
+ src: ast::FloatType::F16
+ }
+ ), a)
+ },
+ "cvt" <f:".ftz"?> <s:".sat"?> ".f32" ".f16" <a:Arg2> => {
+ ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat(
+ ast::CvtDesc {
+ rounding: None,
+ flush_to_zero: Some(f.is_some()),
+ saturate: s.is_some(),
+ dst: ast::FloatType::F32,
+ src: ast::FloatType::F16
+ }
+ ), a)
+ },
+ "cvt" <s:".sat"?> ".f64" ".f16" <a:Arg2> => {
+ ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat(
+ ast::CvtDesc {
+ rounding: None,
+ flush_to_zero: None,
+ saturate: s.is_some(),
+ dst: ast::FloatType::F64,
+ src: ast::FloatType::F16
+ }
+ ), a)
+ },
+ "cvt" <r:RoundingModeFloat> <f:".ftz"?> <s:".sat"?> ".f16" ".f32" <a:Arg2> => {
+ ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat(
+ ast::CvtDesc {
+ rounding: Some(r),
+ flush_to_zero: Some(f.is_some()),
+ saturate: s.is_some(),
+ dst: ast::FloatType::F16,
+ src: ast::FloatType::F32
+ }
+ ), a)
+ },
+ "cvt" <r:RoundingModeInt?> <f:".ftz"?> <s:".sat"?> ".f32" ".f32" <a:Arg2> => {
+ ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat(
+ ast::CvtDesc {
+ rounding: r,
+ flush_to_zero: Some(f.is_some()),
+ saturate: s.is_some(),
+ dst: ast::FloatType::F32,
+ src: ast::FloatType::F32
+ }
+ ), a)
+ },
+ "cvt" <s:".sat"?> ".f64" ".f32" <a:Arg2> => {
+ ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat(
+ ast::CvtDesc {
+ rounding: None,
+ flush_to_zero: None,
+ saturate: s.is_some(),
+ dst: ast::FloatType::F64,
+ src: ast::FloatType::F32
+ }
+ ), a)
+ },
+ "cvt" <r:RoundingModeFloat> <s:".sat"?> ".f16" ".f64" <a:Arg2> => {
+ ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat(
+ ast::CvtDesc {
+ rounding: Some(r),
+ flush_to_zero: None,
+ saturate: s.is_some(),
+ dst: ast::FloatType::F16,
+ src: ast::FloatType::F64
+ }
+ ), a)
+ },
+ "cvt" <r:RoundingModeFloat> <f:".ftz"?> <s:".sat"?> ".f32" ".f64" <a:Arg2> => {
+ ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat(
+ ast::CvtDesc {
+ rounding: Some(r),
+ flush_to_zero: Some(s.is_some()),
+ saturate: s.is_some(),
+ dst: ast::FloatType::F32,
+ src: ast::FloatType::F64
+ }
+ ), a)
+ },
+ "cvt" <r:RoundingModeInt?> <s:".sat"?> ".f64" ".f64" <a:Arg2> => {
+ ast::Instruction::Cvt(ast::CvtDetails::FloatFromFloat(
+ ast::CvtDesc {
+ rounding: r,
+ flush_to_zero: None,
+ saturate: s.is_some(),
+ dst: ast::FloatType::F64,
+ src: ast::FloatType::F64
+ }
+ ), a)
+ },
+};
+
+CvtTypeInt: ast::IntType = {
+ ".u8" => ast::IntType::U8,
+ ".u16" => ast::IntType::U16,
+ ".u32" => ast::IntType::U32,
+ ".u64" => ast::IntType::U64,
+ ".s8" => ast::IntType::S8,
+ ".s16" => ast::IntType::S16,
+ ".s32" => ast::IntType::S32,
+ ".s64" => ast::IntType::S64,
+};
+
+CvtTypeFloat: ast::FloatType = {
+ ".f16" => ast::FloatType::F16,
+ ".f32" => ast::FloatType::F32,
+ ".f64" => ast::FloatType::F64,
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-shl
+InstShl: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "shl" <t:ShlType> <a:Arg3> => ast::Instruction::Shl(t, a)
+};
+
+ShlType: ast::ShlType = {
+ ".b16" => ast::ShlType::B16,
+ ".b32" => ast::ShlType::B32,
+ ".b64" => ast::ShlType::B64,
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-shr
+InstShr: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "shr" <t:ShrType> <a:Arg3> => ast::Instruction::Shr(t, a)
+};
+
+ShrType: ast::ShrType = {
+ ".b16" => ast::ShrType::B16,
+ ".b32" => ast::ShrType::B32,
+ ".b64" => ast::ShrType::B64,
+ ".u16" => ast::ShrType::U16,
+ ".u32" => ast::ShrType::U32,
+ ".u64" => ast::ShrType::U64,
+ ".s16" => ast::ShrType::S16,
+ ".s32" => ast::ShrType::S32,
+ ".s64" => ast::ShrType::S64,
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-st
+// Warning: NVIDIA documentation is incorrect, you can specify scope only once
+InstSt: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "st" <q:LdStQualifier?> <ss:StStateSpace?> <cop:StCacheOperator?> <t:LdStType> <src1:MemoryOperand> "," <src2:SrcOperandVec> => {
+ ast::Instruction::St(
+ ast::StData {
+ qualifier: q.unwrap_or(ast::LdStQualifier::Weak),
+ state_space: ss.unwrap_or(ast::StStateSpace::Generic),
+ caching: cop.unwrap_or(ast::StCacheOperator::Writeback),
+ typ: t
+ },
+ ast::Arg2St { src1:src1, src2:src2 }
+ )
+ }
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#using-addresses-arrays-and-vectors
+MemoryOperand: ast::Operand<&'input str> = {
+ "[" <o:Operand> "]" => o
+}
+
+StStateSpace: ast::StStateSpace = {
+ ".global" => ast::StStateSpace::Global,
+ ".local" => ast::StStateSpace::Local,
+ ".param" => ast::StStateSpace::Param,
+ ".shared" => ast::StStateSpace::Shared,
+};
+
+StCacheOperator: ast::StCacheOperator = {
+ ".wb" => ast::StCacheOperator::Writeback,
+ ".cg" => ast::StCacheOperator::L2Only,
+ ".cs" => ast::StCacheOperator::Streaming,
+ ".wt" => ast::StCacheOperator::Writethrough,
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-ret
+InstRet: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "ret" <u:".uni"?> => ast::Instruction::Ret(ast::RetData { uniform: u.is_some() })
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cvta
+InstCvta: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "cvta" <from:CvtaStateSpace> <s:CvtaSize> <a:Arg2> => {
+ ast::Instruction::Cvta(ast::CvtaDetails {
+ to: ast::CvtaStateSpace::Generic,
+ from,
+ size: s
+ },
+ a)
+ },
+ "cvta" ".to" <to:CvtaStateSpace> <s:CvtaSize> <a:Arg2> => {
+ ast::Instruction::Cvta(ast::CvtaDetails {
+ to,
+ from: ast::CvtaStateSpace::Generic,
+ size: s
+ },
+ a)
+ }
+}
+
+CvtaStateSpace: ast::CvtaStateSpace = {
+ ".const" => ast::CvtaStateSpace::Const,
+ ".global" => ast::CvtaStateSpace::Global,
+ ".local" => ast::CvtaStateSpace::Local,
+ ".shared" => ast::CvtaStateSpace::Shared,
+}
+
+CvtaSize: ast::CvtaSize = {
+ ".u32" => ast::CvtaSize::U32,
+ ".u64" => ast::CvtaSize::U64,
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-call
+InstCall: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "call" <u:".uni"?> <args:ArgCall> => {
+ let (ret_params, func, param_list) = args;
+ ast::Instruction::Call(ast::CallInst { uniform: u.is_some(), ret_params, func, param_list })
+ }
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-abs
+InstAbs: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "abs" <t:SignedIntType> <a:Arg2> => {
+ ast::Instruction::Abs(ast::AbsDetails { flush_to_zero: None, typ: t }, a)
+ },
+ "abs" <f:".ftz"?> ".f32" <a:Arg2> => {
+ ast::Instruction::Abs(ast::AbsDetails { flush_to_zero: Some(f.is_some()), typ: ast::ScalarType::F32 }, a)
+ },
+ "abs" ".f64" <a:Arg2> => {
+ ast::Instruction::Abs(ast::AbsDetails { flush_to_zero: None, typ: ast::ScalarType::F64 }, a)
+ },
+ "abs" <f:".ftz"?> ".f16" <a:Arg2> => {
+ ast::Instruction::Abs(ast::AbsDetails { flush_to_zero: Some(f.is_some()), typ: ast::ScalarType::F16 }, a)
+ },
+ "abs" <f:".ftz"?> ".f16x2" <a:Arg2> => {
+ ast::Instruction::Abs(ast::AbsDetails { flush_to_zero: Some(f.is_some()), typ: ast::ScalarType::F16x2 }, a)
+ },
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-mad
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-mad
+InstMad: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "mad" <d:MulDetails> <a:Arg4> => ast::Instruction::Mad(d, a),
+ "mad" ".hi" ".sat" ".s32" => todo!(),
+ "fma" <f:ArithFloatMustRound> <a:Arg4> => ast::Instruction::Mad(ast::MulDetails::Float(f), a),
+};
+
+SignedIntType: ast::ScalarType = {
+ ".s16" => ast::ScalarType::S16,
+ ".s32" => ast::ScalarType::S32,
+ ".s64" => ast::ScalarType::S64,
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-or
+InstOr: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "or" <d:BooleanType> <a:Arg3> => ast::Instruction::Or(d, a),
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-and
+InstAnd: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "and" <d:BooleanType> <a:Arg3> => ast::Instruction::And(d, a),
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-rcp
+InstRcp: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "rcp" <rounding:RcpRoundingMode> <ftz:".ftz"?> ".f32" <a:Arg2> => {
+ let details = ast::RcpDetails {
+ rounding,
+ flush_to_zero: Some(ftz.is_some()),
+ is_f64: false,
+ };
+ ast::Instruction::Rcp(details, a)
+ },
+ "rcp" <rn:RoundingModeFloat> ".f64" <a:Arg2> => {
+ let details = ast::RcpDetails {
+ rounding: Some(rn),
+ flush_to_zero: None,
+ is_f64: true,
+ };
+ ast::Instruction::Rcp(details, a)
+ }
+};
+
+RcpRoundingMode: Option<ast::RoundingMode> = {
+ ".approx" => None,
+ <r:RoundingModeFloat> => Some(r)
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-sub
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-sub
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-floating-point-instructions-sub
+InstSub: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "sub" <d:ArithDetails> <a:Arg3> => ast::Instruction::Sub(d, a),
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-min
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-min
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-floating-point-instructions-min
+InstMin: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "min" <d:MinMaxDetails> <a:Arg3> => ast::Instruction::Min(d, a),
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-max
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-max
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-floating-point-instructions-max
+InstMax: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "max" <d:MinMaxDetails> <a:Arg3> => ast::Instruction::Max(d, a),
+};
+
+MinMaxDetails: ast::MinMaxDetails = {
+ <t:UIntType> => ast::MinMaxDetails::Unsigned(t),
+ <t:SIntType> => ast::MinMaxDetails::Signed(t),
+ <ftz:".ftz"?> <nan:".NaN"?> ".f32" => ast::MinMaxDetails::Float(
+ ast::MinMaxFloat{ flush_to_zero: Some(ftz.is_some()), nan: nan.is_some(), typ: ast::FloatType::F32 }
+ ),
+ ".f64" => ast::MinMaxDetails::Float(
+ ast::MinMaxFloat{ flush_to_zero: None, nan: false, typ: ast::FloatType::F64 }
+ ),
+ <ftz:".ftz"?> <nan:".NaN"?> ".f16" => ast::MinMaxDetails::Float(
+ ast::MinMaxFloat{ flush_to_zero: Some(ftz.is_some()), nan: nan.is_some(), typ: ast::FloatType::F16 }
+ ),
+ <ftz:".ftz"?> <nan:".NaN"?> ".f16x2" => ast::MinMaxDetails::Float(
+ ast::MinMaxFloat{ flush_to_zero: Some(ftz.is_some()), nan: nan.is_some(), typ: ast::FloatType::F16x2 }
+ )
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#comparison-and-selection-instructions-selp
+InstSelp: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "selp" <t:SelpType> <a:Arg4> => ast::Instruction::Selp(t, a),
+};
+
+SelpType: ast::SelpType = {
+ ".b16" => ast::SelpType::B16,
+ ".b32" => ast::SelpType::B32,
+ ".b64" => ast::SelpType::B64,
+ ".u16" => ast::SelpType::U16,
+ ".u32" => ast::SelpType::U32,
+ ".u64" => ast::SelpType::U64,
+ ".s16" => ast::SelpType::S16,
+ ".s32" => ast::SelpType::S32,
+ ".s64" => ast::SelpType::S64,
+ ".f32" => ast::SelpType::F32,
+ ".f64" => ast::SelpType::F64,
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-bar
+InstBar: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "barrier" ".sync" ".aligned" <a:Arg1Bar> => ast::Instruction::Bar(ast::BarDetails::SyncAligned, a),
+ "bar" ".sync" <a:Arg1Bar> => ast::Instruction::Bar(ast::BarDetails::SyncAligned, a)
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-atom
+// The documentation does not mention all spported operations:
+// * Operation .add requires .u32 or .s32 or .u64 or .f64 or f16 or f16x2 or .f32
+// * Operation .inc requires .u32 type for instuction
+// * Operation .dec requires .u32 type for instuction
+// Otherwise as documented
+InstAtom: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "atom" <sema:AtomSemantics?> <scope:MemScope?> <space:AtomSpace?> <op:AtomBitOp> <typ:BitType> <a:Arg3Atom> => {
+ let details = ast::AtomDetails {
+ semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed),
+ scope: scope.unwrap_or(ast::MemScope::Gpu),
+ space: space.unwrap_or(ast::AtomSpace::Generic),
+ inner: ast::AtomInnerDetails::Bit { op, typ }
+ };
+ ast::Instruction::Atom(details,a)
+ },
+ "atom" <sema:AtomSemantics?> <scope:MemScope?> <space:AtomSpace?> ".inc" ".u32" <a:Arg3Atom> => {
+ let details = ast::AtomDetails {
+ semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed),
+ scope: scope.unwrap_or(ast::MemScope::Gpu),
+ space: space.unwrap_or(ast::AtomSpace::Generic),
+ inner: ast::AtomInnerDetails::Unsigned {
+ op: ast::AtomUIntOp::Inc,
+ typ: ast::UIntType::U32
+ }
+ };
+ ast::Instruction::Atom(details,a)
+ },
+ "atom" <sema:AtomSemantics?> <scope:MemScope?> <space:AtomSpace?> ".dec" ".u32" <a:Arg3Atom> => {
+ let details = ast::AtomDetails {
+ semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed),
+ scope: scope.unwrap_or(ast::MemScope::Gpu),
+ space: space.unwrap_or(ast::AtomSpace::Generic),
+ inner: ast::AtomInnerDetails::Unsigned {
+ op: ast::AtomUIntOp::Dec,
+ typ: ast::UIntType::U32
+ }
+ };
+ ast::Instruction::Atom(details,a)
+ },
+ "atom" <sema:AtomSemantics?> <scope:MemScope?> <space:AtomSpace?> ".add" <typ:FloatType> <a:Arg3Atom> => {
+ let op = ast::AtomFloatOp::Add;
+ let details = ast::AtomDetails {
+ semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed),
+ scope: scope.unwrap_or(ast::MemScope::Gpu),
+ space: space.unwrap_or(ast::AtomSpace::Generic),
+ inner: ast::AtomInnerDetails::Float { op, typ }
+ };
+ ast::Instruction::Atom(details,a)
+ },
+ "atom" <sema:AtomSemantics?> <scope:MemScope?> <space:AtomSpace?> <op: AtomUIntOp> <typ:UIntType3264> <a:Arg3Atom> => {
+ let details = ast::AtomDetails {
+ semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed),
+ scope: scope.unwrap_or(ast::MemScope::Gpu),
+ space: space.unwrap_or(ast::AtomSpace::Generic),
+ inner: ast::AtomInnerDetails::Unsigned { op, typ }
+ };
+ ast::Instruction::Atom(details,a)
+ },
+ "atom" <sema:AtomSemantics?> <scope:MemScope?> <space:AtomSpace?> <op: AtomSIntOp> <typ:SIntType3264> <a:Arg3Atom> => {
+ let details = ast::AtomDetails {
+ semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed),
+ scope: scope.unwrap_or(ast::MemScope::Gpu),
+ space: space.unwrap_or(ast::AtomSpace::Generic),
+ inner: ast::AtomInnerDetails::Signed { op, typ }
+ };
+ ast::Instruction::Atom(details,a)
+ }
+}
+
+InstAtomCas: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "atom" <sema:AtomSemantics?> <scope:MemScope?> <space:AtomSpace?> ".cas" <typ:BitType> <a:Arg4Atom> => {
+ let details = ast::AtomCasDetails {
+ semantics: sema.unwrap_or(ast::AtomSemantics::Relaxed),
+ scope: scope.unwrap_or(ast::MemScope::Gpu),
+ space: space.unwrap_or(ast::AtomSpace::Generic),
+ typ,
+ };
+ ast::Instruction::AtomCas(details,a)
+ },
+}
+
+AtomSemantics: ast::AtomSemantics = {
+ ".relaxed" => ast::AtomSemantics::Relaxed,
+ ".acquire" => ast::AtomSemantics::Acquire,
+ ".release" => ast::AtomSemantics::Release,
+ ".acq_rel" => ast::AtomSemantics::AcquireRelease
+}
+
+AtomSpace: ast::AtomSpace = {
+ ".global" => ast::AtomSpace::Global,
+ ".shared" => ast::AtomSpace::Shared
+}
+
+AtomBitOp: ast::AtomBitOp = {
+ ".and" => ast::AtomBitOp::And,
+ ".or" => ast::AtomBitOp::Or,
+ ".xor" => ast::AtomBitOp::Xor,
+ ".exch" => ast::AtomBitOp::Exchange,
+}
+
+AtomUIntOp: ast::AtomUIntOp = {
+ ".add" => ast::AtomUIntOp::Add,
+ ".min" => ast::AtomUIntOp::Min,
+ ".max" => ast::AtomUIntOp::Max,
+}
+
+AtomSIntOp: ast::AtomSIntOp = {
+ ".add" => ast::AtomSIntOp::Add,
+ ".min" => ast::AtomSIntOp::Min,
+ ".max" => ast::AtomSIntOp::Max,
+}
+
+BitType: ast::BitType = {
+ ".b32" => ast::BitType::B32,
+ ".b64" => ast::BitType::B64,
+}
+
+UIntType3264: ast::UIntType = {
+ ".u32" => ast::UIntType::U32,
+ ".u64" => ast::UIntType::U64,
+}
+
+SIntType3264: ast::SIntType = {
+ ".s32" => ast::SIntType::S32,
+ ".s64" => ast::SIntType::S64,
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-div
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-div
+InstDiv: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "div" <t:UIntType> <a:Arg3> => ast::Instruction::Div(ast::DivDetails::Unsigned(t), a),
+ "div" <t:SIntType> <a:Arg3> => ast::Instruction::Div(ast::DivDetails::Signed(t), a),
+ "div" <kind:DivFloatKind> <ftz:".ftz"?> ".f32" <a:Arg3> => {
+ let inner = ast::DivFloatDetails {
+ typ: ast::FloatType::F32,
+ flush_to_zero: Some(ftz.is_some()),
+ kind
+ };
+ ast::Instruction::Div(ast::DivDetails::Float(inner), a)
+ },
+ "div" <rnd:RoundingModeFloat> ".f64" <a:Arg3> => {
+ let inner = ast::DivFloatDetails {
+ typ: ast::FloatType::F64,
+ flush_to_zero: None,
+ kind: ast::DivFloatKind::Rounding(rnd)
+ };
+ ast::Instruction::Div(ast::DivDetails::Float(inner), a)
+ },
+}
+
+DivFloatKind: ast::DivFloatKind = {
+ ".approx" => ast::DivFloatKind::Approx,
+ ".full" => ast::DivFloatKind::Full,
+ <rnd:RoundingModeFloat> => ast::DivFloatKind::Rounding(rnd),
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-sqrt
+InstSqrt: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "sqrt" ".approx" <ftz:".ftz"?> ".f32" <a:Arg2> => {
+ let details = ast::SqrtDetails {
+ typ: ast::FloatType::F32,
+ flush_to_zero: Some(ftz.is_some()),
+ kind: ast::SqrtKind::Approx,
+ };
+ ast::Instruction::Sqrt(details, a)
+ },
+ "sqrt" <rnd:RoundingModeFloat> <ftz:".ftz"?> ".f32" <a:Arg2> => {
+ let details = ast::SqrtDetails {
+ typ: ast::FloatType::F32,
+ flush_to_zero: Some(ftz.is_some()),
+ kind: ast::SqrtKind::Rounding(rnd),
+ };
+ ast::Instruction::Sqrt(details, a)
+ },
+ "sqrt" <rnd:RoundingModeFloat> ".f64" <a:Arg2> => {
+ let details = ast::SqrtDetails {
+ typ: ast::FloatType::F64,
+ flush_to_zero: None,
+ kind: ast::SqrtKind::Rounding(rnd),
+ };
+ ast::Instruction::Sqrt(details, a)
+ }
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-rsqrt
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-rsqrt-approx-ftz-f64
+InstRsqrt: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "rsqrt" ".approx" <ftz:".ftz"?> ".f32" <a:Arg2> => {
+ let details = ast::RsqrtDetails {
+ typ: ast::FloatType::F32,
+ flush_to_zero: ftz.is_some(),
+ };
+ ast::Instruction::Rsqrt(details, a)
+ },
+ "rsqrt" ".approx" <ftz:".ftz"?> ".f64" <a:Arg2> => {
+ let details = ast::RsqrtDetails {
+ typ: ast::FloatType::F64,
+ flush_to_zero: ftz.is_some(),
+ };
+ ast::Instruction::Rsqrt(details, a)
+ },
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-neg
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-neg
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-floating-point-instructions-neg
+InstNeg: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "neg" <ftz:".ftz"?> <typ:NegTypeFtz> <a:Arg2> => {
+ let details = ast::NegDetails {
+ typ,
+ flush_to_zero: Some(ftz.is_some()),
+ };
+ ast::Instruction::Neg(details, a)
+ },
+ "neg" <typ:NegTypeNonFtz> <a:Arg2> => {
+ let details = ast::NegDetails {
+ typ,
+ flush_to_zero: None,
+ };
+ ast::Instruction::Neg(details, a)
+ },
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-sin
+InstSin: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "sin" ".approx" <ftz:".ftz"?> ".f32" <arg:Arg2> => {
+ ast::Instruction::Sin{ flush_to_zero: ftz.is_some(), arg }
+ },
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-cos
+InstCos: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "cos" ".approx" <ftz:".ftz"?> ".f32" <arg:Arg2> => {
+ ast::Instruction::Cos{ flush_to_zero: ftz.is_some(), arg }
+ },
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-lg2
+InstLg2: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "lg2" ".approx" <ftz:".ftz"?> ".f32" <arg:Arg2> => {
+ ast::Instruction::Lg2{ flush_to_zero: ftz.is_some(), arg }
+ },
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-ex2
+InstEx2: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "ex2" ".approx" <ftz:".ftz"?> ".f32" <arg:Arg2> => {
+ ast::Instruction::Ex2{ flush_to_zero: ftz.is_some(), arg }
+ },
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-clz
+InstClz: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "clz" <typ:BitType> <arg:Arg2> => ast::Instruction::Clz{ <> }
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-brev
+InstBrev: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "brev" <typ:BitType> <arg:Arg2> => ast::Instruction::Brev{ <> }
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-popc
+InstPopc: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "popc" <typ:BitType> <arg:Arg2> => ast::Instruction::Popc{ <> }
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-xor
+InstXor: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "xor" <typ:BooleanType> <arg:Arg3> => ast::Instruction::Xor{ <> }
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-bfe
+InstBfe: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "bfe" <typ:IntType3264> <arg:Arg4> => ast::Instruction::Bfe{ <> }
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-rem
+InstRem: ast::Instruction<ast::ParsedArgParams<'input>> = {
+ "rem" <typ:IntType> <arg:Arg3> => ast::Instruction::Rem{ <> }
+}
+
+
+NegTypeFtz: ast::ScalarType = {
+ ".f16" => ast::ScalarType::F16,
+ ".f16x2" => ast::ScalarType::F16x2,
+ ".f32" => ast::ScalarType::F32,
+}
+
+NegTypeNonFtz: ast::ScalarType = {
+ ".s16" => ast::ScalarType::S16,
+ ".s32" => ast::ScalarType::S32,
+ ".s64" => ast::ScalarType::S64,
+ ".f64" => ast::ScalarType::F64
+}
+
+ArithDetails: ast::ArithDetails = {
+ <t:UIntType> => ast::ArithDetails::Unsigned(t),
+ <t:SIntType> => ast::ArithDetails::Signed(ast::ArithSInt {
+ typ: t,
+ saturate: false,
+ }),
+ ".sat" ".s32" => ast::ArithDetails::Signed(ast::ArithSInt {
+ typ: ast::SIntType::S32,
+ saturate: true,
+ }),
+ <f:ArithFloat> => ast::ArithDetails::Float(f)
+}
+
+ArithFloat: ast::ArithFloat = {
+ <rn:RoundingModeFloat?> <ftz:".ftz"?> <sat:".sat"?> ".f32" => ast::ArithFloat {
+ typ: ast::FloatType::F32,
+ rounding: rn,
+ flush_to_zero: Some(ftz.is_some()),
+ saturate: sat.is_some(),
+ },
+ <rn:RoundingModeFloat?> ".f64" => ast::ArithFloat {
+ typ: ast::FloatType::F64,
+ rounding: rn,
+ flush_to_zero: None,
+ saturate: false,
+ },
+ <rn:".rn"?> <ftz:".ftz"?> <sat:".sat"?> ".f16" => ast::ArithFloat {
+ typ: ast::FloatType::F16,
+ rounding: rn.map(|_| ast::RoundingMode::NearestEven),
+ flush_to_zero: Some(ftz.is_some()),
+ saturate: sat.is_some(),
+ },
+ <rn:".rn"?> <ftz:".ftz"?> <sat:".sat"?> ".f16x2" => ast::ArithFloat {
+ typ: ast::FloatType::F16x2,
+ rounding: rn.map(|_| ast::RoundingMode::NearestEven),
+ flush_to_zero: Some(ftz.is_some()),
+ saturate: sat.is_some(),
+ },
+}
+
+ArithFloatMustRound: ast::ArithFloat = {
+ <rn:RoundingModeFloat> <ftz:".ftz"?> <sat:".sat"?> ".f32" => ast::ArithFloat {
+ typ: ast::FloatType::F32,
+ rounding: Some(rn),
+ flush_to_zero: Some(ftz.is_some()),
+ saturate: sat.is_some(),
+ },
+ <rn:RoundingModeFloat> ".f64" => ast::ArithFloat {
+ typ: ast::FloatType::F64,
+ rounding: Some(rn),
+ flush_to_zero: None,
+ saturate: false,
+ },
+ ".rn" <ftz:".ftz"?> <sat:".sat"?> ".f16" => ast::ArithFloat {
+ typ: ast::FloatType::F16,
+ rounding: Some(ast::RoundingMode::NearestEven),
+ flush_to_zero: Some(ftz.is_some()),
+ saturate: sat.is_some(),
+ },
+ ".rn" <ftz:".ftz"?> <sat:".sat"?> ".f16x2" => ast::ArithFloat {
+ typ: ast::FloatType::F16x2,
+ rounding: Some(ast::RoundingMode::NearestEven),
+ flush_to_zero: Some(ftz.is_some()),
+ saturate: sat.is_some(),
+ },
+}
+
+Operand: ast::Operand<&'input str> = {
+ <r:ExtendedID> => ast::Operand::Reg(r),
+ <r:ExtendedID> "+" <offset:S32Num> => ast::Operand::RegOffset(r, offset),
+ <x:ImmediateValue> => ast::Operand::Imm(x)
+};
+
+CallOperand: ast::Operand<&'input str> = {
+ <r:ExtendedID> => ast::Operand::Reg(r),
+ <x:ImmediateValue> => ast::Operand::Imm(x)
+};
+
+// TODO: start parsing whole constants sub-language:
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#constants
+ImmediateValue: ast::ImmediateValue = {
+ // TODO: treat negation correctly
+ <neg:"-"?> <x:NumToken> =>? {
+ let (num, radix, is_unsigned) = x;
+ if neg.is_some() {
+ match i64::from_str_radix(num, radix) {
+ Ok(x) => Ok(ast::ImmediateValue::S64(-x)),
+ Err(err) => Err(ParseError::User { error: ast::PtxError::ParseInt(err) })
+ }
+ } else if is_unsigned {
+ match u64::from_str_radix(num, radix) {
+ Ok(x) => Ok(ast::ImmediateValue::U64(x)),
+ Err(err) => Err(ParseError::User { error: ast::PtxError::ParseInt(err) })
+ }
+ } else {
+ match i64::from_str_radix(num, radix) {
+ Ok(x) => Ok(ast::ImmediateValue::S64(x)),
+ Err(_) => {
+ match u64::from_str_radix(num, radix) {
+ Ok(x) => Ok(ast::ImmediateValue::U64(x)),
+ Err(err) => Err(ParseError::User { error: ast::PtxError::ParseInt(err) })
+ }
+ }
+ }
+ }
+ },
+ <f:F32Num> => {
+ ast::ImmediateValue::F32(f)
+ },
+ <f:F64Num> => {
+ ast::ImmediateValue::F64(f)
+ }
+}
+
+Arg1: ast::Arg1<ast::ParsedArgParams<'input>> = {
+ <src:ExtendedID> => ast::Arg1{<>}
+};
+
+Arg1Bar: ast::Arg1Bar<ast::ParsedArgParams<'input>> = {
+ <src:Operand> => ast::Arg1Bar{<>}
+};
+
+Arg2: ast::Arg2<ast::ParsedArgParams<'input>> = {
+ <dst:DstOperand> "," <src:Operand> => ast::Arg2{<>}
+};
+
+MemberOperand: (&'input str, u8) = {
+ <pref:ExtendedID> "." <suf:ExtendedID> =>? {
+ let suf_idx = vector_index(suf)?;
+ Ok((pref, suf_idx))
+ },
+ <pref:ExtendedID> <suf:DotID> =>? {
+ let suf_idx = vector_index(&suf[1..])?;
+ Ok((pref, suf_idx))
+ }
+};
+
+VectorExtract: Vec<&'input str> = {
+ "{" <r1:ExtendedID> "," <r2:ExtendedID> "}" => {
+ vec![r1, r2]
+ },
+ "{" <r1:ExtendedID> "," <r2:ExtendedID> "," <r3:ExtendedID> "," <r4:ExtendedID> "}" => {
+ vec![r1, r2, r3, r4]
+ },
+};
+
+Arg3: ast::Arg3<ast::ParsedArgParams<'input>> = {
+ <dst:DstOperand> "," <src1:Operand> "," <src2:Operand> => ast::Arg3{<>}
+};
+
+Arg3Atom: ast::Arg3<ast::ParsedArgParams<'input>> = {
+ <dst:DstOperand> "," "[" <src1:Operand> "]" "," <src2:Operand> => ast::Arg3{<>}
+};
+
+Arg4: ast::Arg4<ast::ParsedArgParams<'input>> = {
+ <dst:DstOperand> "," <src1:Operand> "," <src2:Operand> "," <src3:Operand> => ast::Arg4{<>}
+};
+
+Arg4Atom: ast::Arg4<ast::ParsedArgParams<'input>> = {
+ <dst:DstOperand> "," "[" <src1:Operand> "]" "," <src2:Operand> "," <src3:Operand> => ast::Arg4{<>}
+};
+
+Arg4Setp: ast::Arg4Setp<ast::ParsedArgParams<'input>> = {
+ <dst1:ExtendedID> <dst2:OptionalDst?> "," <src1:Operand> "," <src2:Operand> => ast::Arg4Setp{<>}
+};
+
+// TODO: pass src3 negation somewhere
+Arg5Setp: ast::Arg5Setp<ast::ParsedArgParams<'input>> = {
+ <dst1:ExtendedID> <dst2:OptionalDst?> "," <src1:Operand> "," <src2:Operand> "," "!"? <src3:Operand> => ast::Arg5Setp{<>}
+};
+
+ArgCall: (Vec<&'input str>, &'input str, Vec<ast::Operand<&'input str>>) = {
+ "(" <ret_params:Comma<ExtendedID>> ")" "," <func:ExtendedID> "," "(" <param_list:Comma<CallOperand>> ")" => {
+ (ret_params, func, param_list)
+ },
+ <func:ExtendedID> "," "(" <param_list:Comma<CallOperand>> ")" => (Vec::new(), func, param_list),
+ <func:ExtendedID> => (Vec::new(), func, Vec::<ast::Operand<_>>::new()),
+};
+
+OptionalDst: &'input str = {
+ "|" <dst2:ExtendedID> => dst2
+}
+
+SrcOperand: ast::Operand<&'input str> = {
+ <r:ExtendedID> => ast::Operand::Reg(r),
+ <r:ExtendedID> "+" <offset:S32Num> => ast::Operand::RegOffset(r, offset),
+ <x:ImmediateValue> => ast::Operand::Imm(x),
+ <mem_op:MemberOperand> => {
+ let (reg, idx) = mem_op;
+ ast::Operand::VecMember(reg, idx)
+ }
+}
+
+SrcOperandVec: ast::Operand<&'input str> = {
+ <normal:SrcOperand> => normal,
+ <vec:VectorExtract> => ast::Operand::VecPack(vec),
+}
+
+DstOperand: ast::Operand<&'input str> = {
+ <r:ExtendedID> => ast::Operand::Reg(r),
+ <mem_op:MemberOperand> => {
+ let (reg, idx) = mem_op;
+ ast::Operand::VecMember(reg, idx)
+ }
+}
+
+DstOperandVec: ast::Operand<&'input str> = {
+ <normal:DstOperand> => normal,
+ <vec:VectorExtract> => ast::Operand::VecPack(vec),
+}
+
+VectorPrefix: u8 = {
+ ".v2" => 2,
+ ".v4" => 4
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#debugging-directives-file
+File = {
+ ".file" U32Num String ("," U32Num "," U32Num)?
+};
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#debugging-directives-section
+Section = {
+ ".section" DotID "{" SectionDwarfLines* "}"
+};
+
+SectionDwarfLines: () = {
+ AnyBitType Comma<U32Num>,
+ ".b32" SectionLabel,
+ ".b64" SectionLabel,
+ ".b32" SectionLabel "+" U32Num,
+ ".b64" SectionLabel "+" U32Num,
+};
+
+SectionLabel = {
+ ID,
+ DotID
+};
+
+AnyBitType = {
+ ".b8", ".b16", ".b32", ".b64"
+};
+
+VariableScalar<T>: (Option<u32>, T, &'input str) = {
+ <align:Align?> <v_type:T> <name:ExtendedID> => {
+ (align, v_type, name)
+ }
+}
+
+VariableVector<T>: (Option<u32>, u8, T, &'input str) = {
+ <align:Align?> <v_len:VectorPrefix> <v_type:T> <name:ExtendedID> => {
+ (align, v_len, v_type, name)
+ }
+}
+
+// empty dimensions [0] means it's a pointer
+VariableArrayOrPointer<T>: (Option<u32>, T, &'input str, ast::ArrayOrPointer) = {
+ <align:Align?> <typ:SizedScalarType> <name:ExtendedID> <dims:ArrayDimensions> <init:ArrayInitializer?> =>? {
+ let mut dims = dims;
+ let array_init = match init {
+ Some(init) => {
+ let init_vec = init.to_vec(typ, &mut dims)?;
+ ast::ArrayOrPointer::Array { dimensions: dims, init: init_vec }
+ }
+ None => {
+ if dims.len() > 1 && dims.contains(&0) {
+ return Err(ParseError::User { error: ast::PtxError::ZeroDimensionArray })
+ }
+ match &*dims {
+ [0] => ast::ArrayOrPointer::Pointer,
+ _ => ast::ArrayOrPointer::Array { dimensions: dims, init: Vec::new() }
+ }
+ }
+ };
+ Ok((align, typ, name, array_init))
+ }
+}
+
+// [0] and [] are treated the same
+ArrayDimensions: Vec<u32> = {
+ ArrayEmptyDimension => vec![0u32],
+ ArrayEmptyDimension <dims:ArrayDimension+> => {
+ let mut dims = dims;
+ let mut result = vec![0u32];
+ result.append(&mut dims);
+ result
+ },
+ <dims:ArrayDimension+> => dims
+}
+
+ArrayEmptyDimension = {
+ "[" "]"
+}
+
+ArrayDimension: u32 = {
+ "[" <n:U32Num> "]" => n,
+}
+
+ArrayInitializer: ast::NumsOrArrays<'input> = {
+ "=" <nums:NumsOrArraysBracket> => nums
+}
+
+NumsOrArraysBracket: ast::NumsOrArrays<'input> = {
+ "{" <nums:NumsOrArrays> "}" => nums
+}
+
+NumsOrArrays: ast::NumsOrArrays<'input> = {
+ <n:Comma<NumsOrArraysBracket>> => ast::NumsOrArrays::Arrays(n),
+ <n:CommaNonEmpty<NumToken>> => ast::NumsOrArrays::Nums(n.into_iter().map(|(x,radix,_)| (x, radix)).collect()),
+}
+
+Comma<T>: Vec<T> = {
+ <v:(<T> ",")*> <e:T?> => match e {
+ None => v,
+ Some(e) => {
+ let mut v = v;
+ v.push(e);
+ v
+ }
+ }
+};
+
+CommaNonEmpty<T>: Vec<T> = {
+ <v:(<T> ",")*> <e:T> => {
+ let mut v = v;
+ v.push(e);
+ v
+ }
+};
+
+#[inline]
+Or<T1, T2>: T1 = {
+ T1,
+ T2
+} \ No newline at end of file
diff --git a/ptx/src/test/_Z9vectorAddPKfS0_Pfi.ptx b/ptx/src/test/_Z9vectorAddPKfS0_Pfi.ptx
new file mode 100644
index 0000000..e5bc3d1
--- /dev/null
+++ b/ptx/src/test/_Z9vectorAddPKfS0_Pfi.ptx
@@ -0,0 +1,10423 @@
+
+
+
+
+
+
+
+
+.version 7.0
+.target sm_80, debug
+.address_size 64
+
+
+.func (.param .b32 func_retval0) fabsf
+(
+.param .b32 fabsf_param_0
+)
+;
+
+.weak .func (.param .b32 func_retval0) cudaMalloc(
+.param .b64 cudaMalloc_param_0,
+.param .b64 cudaMalloc_param_1
+)
+{
+.local .align 8 .b8 __local_depot0[8];
+.reg .b64 %SP;
+.reg .b64 %SPL;
+.reg .b32 %r<3>;
+.reg .b64 %rd<5>;
+
+
+.loc 2 75 1
+func_begin0:
+.loc 2 0 0
+
+.loc 2 75 1
+
+mov.u64 %SPL, __local_depot0;
+cvta.local.u64 %SP, %SPL;
+ld.param.u64 %rd1, [cudaMalloc_param_0];
+ld.param.u64 %rd2, [cudaMalloc_param_1];
+mov.u64 %rd3, %rd1;
+st.u64 [%SP+0], %rd3;
+mov.b64 %rd4, %rd2;
+func_exec_begin0:
+.loc 2 77 3
+tmp0:
+mov.u32 %r1, 999;
+mov.b32 %r2, %r1;
+st.param.b32 [func_retval0+0], %r2;
+ret;
+tmp1:
+func_end0:
+}
+
+
+.weak .func (.param .b32 func_retval0) cudaFuncGetAttributes(
+.param .b64 cudaFuncGetAttributes_param_0,
+.param .b64 cudaFuncGetAttributes_param_1
+)
+{
+.local .align 8 .b8 __local_depot1[8];
+.reg .b64 %SP;
+.reg .b64 %SPL;
+.reg .b32 %r<3>;
+.reg .b64 %rd<5>;
+
+
+.loc 2 80 1
+func_begin1:
+.loc 2 0 0
+
+.loc 2 80 1
+
+mov.u64 %SPL, __local_depot1;
+cvta.local.u64 %SP, %SPL;
+ld.param.u64 %rd1, [cudaFuncGetAttributes_param_0];
+ld.param.u64 %rd2, [cudaFuncGetAttributes_param_1];
+mov.u64 %rd3, %rd1;
+st.u64 [%SP+0], %rd3;
+mov.u64 %rd4, %rd2;
+func_exec_begin1:
+.loc 2 82 3
+tmp2:
+mov.u32 %r1, 999;
+mov.b32 %r2, %r1;
+st.param.b32 [func_retval0+0], %r2;
+ret;
+tmp3:
+func_end1:
+}
+
+
+.weak .func (.param .b32 func_retval0) cudaDeviceGetAttribute(
+.param .b64 cudaDeviceGetAttribute_param_0,
+.param .b32 cudaDeviceGetAttribute_param_1,
+.param .b32 cudaDeviceGetAttribute_param_2
+)
+{
+.reg .b32 %r<7>;
+.reg .b64 %rd<3>;
+
+
+.loc 2 85 1
+func_begin2:
+.loc 2 0 0
+
+.loc 2 85 1
+
+ld.param.u64 %rd1, [cudaDeviceGetAttribute_param_0];
+ld.param.u32 %r1, [cudaDeviceGetAttribute_param_1];
+ld.param.u32 %r2, [cudaDeviceGetAttribute_param_2];
+mov.u64 %rd2, %rd1;
+mov.b32 %r3, %r1;
+mov.b32 %r4, %r2;
+func_exec_begin2:
+.loc 2 87 3
+tmp4:
+mov.u32 %r5, 999;
+mov.b32 %r6, %r5;
+st.param.b32 [func_retval0+0], %r6;
+ret;
+tmp5:
+func_end2:
+}
+
+
+.weak .func (.param .b32 func_retval0) cudaGetDevice(
+.param .b64 cudaGetDevice_param_0
+)
+{
+.reg .b32 %r<3>;
+.reg .b64 %rd<3>;
+
+
+.loc 2 90 1
+func_begin3:
+.loc 2 0 0
+
+.loc 2 90 1
+
+ld.param.u64 %rd1, [cudaGetDevice_param_0];
+mov.u64 %rd2, %rd1;
+func_exec_begin3:
+.loc 2 92 3
+tmp6:
+mov.u32 %r1, 999;
+mov.b32 %r2, %r1;
+st.param.b32 [func_retval0+0], %r2;
+ret;
+tmp7:
+func_end3:
+}
+
+
+.weak .func (.param .b32 func_retval0) cudaOccupancyMaxActiveBlocksPerMultiprocessor(
+.param .b64 cudaOccupancyMaxActiveBlocksPerMultiprocessor_param_0,
+.param .b64 cudaOccupancyMaxActiveBlocksPerMultiprocessor_param_1,
+.param .b32 cudaOccupancyMaxActiveBlocksPerMultiprocessor_param_2,
+.param .b64 cudaOccupancyMaxActiveBlocksPerMultiprocessor_param_3
+)
+{
+.reg .b32 %r<5>;
+.reg .b64 %rd<7>;
+
+
+.loc 2 95 1
+func_begin4:
+.loc 2 0 0
+
+.loc 2 95 1
+
+ld.param.u64 %rd1, [cudaOccupancyMaxActiveBlocksPerMultiprocessor_param_0];
+ld.param.u64 %rd2, [cudaOccupancyMaxActiveBlocksPerMultiprocessor_param_1];
+ld.param.u32 %r1, [cudaOccupancyMaxActiveBlocksPerMultiprocessor_param_2];
+ld.param.u64 %rd3, [cudaOccupancyMaxActiveBlocksPerMultiprocessor_param_3];
+mov.u64 %rd4, %rd1;
+mov.u64 %rd5, %rd2;
+mov.b32 %r2, %r1;
+mov.b64 %rd6, %rd3;
+func_exec_begin4:
+.loc 2 97 3
+tmp8:
+mov.u32 %r3, 999;
+mov.b32 %r4, %r3;
+st.param.b32 [func_retval0+0], %r4;
+ret;
+tmp9:
+func_end4:
+}
+
+
+.weak .func (.param .b32 func_retval0) cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags(
+.param .b64 cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags_param_0,
+.param .b64 cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags_param_1,
+.param .b32 cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags_param_2,
+.param .b64 cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags_param_3,
+.param .b32 cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags_param_4
+)
+{
+.reg .b32 %r<7>;
+.reg .b64 %rd<7>;
+
+
+.loc 2 100 1
+func_begin5:
+.loc 2 0 0
+
+.loc 2 100 1
+
+ld.param.u64 %rd1, [cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags_param_0];
+ld.param.u64 %rd2, [cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags_param_1];
+ld.param.u32 %r1, [cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags_param_2];
+ld.param.u64 %rd3, [cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags_param_3];
+ld.param.u32 %r2, [cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags_param_4];
+mov.u64 %rd4, %rd1;
+mov.u64 %rd5, %rd2;
+mov.b32 %r3, %r1;
+mov.b64 %rd6, %rd3;
+mov.b32 %r4, %r2;
+func_exec_begin5:
+.loc 2 102 3
+tmp10:
+mov.u32 %r5, 999;
+mov.b32 %r6, %r5;
+st.param.b32 [func_retval0+0], %r6;
+ret;
+tmp11:
+func_end5:
+}
+
+
+.visible .entry _Z9vectorAddPKfS0_Pfi(
+.param .u64 _Z9vectorAddPKfS0_Pfi_param_0,
+.param .u64 _Z9vectorAddPKfS0_Pfi_param_1,
+.param .u64 _Z9vectorAddPKfS0_Pfi_param_2,
+.param .u32 _Z9vectorAddPKfS0_Pfi_param_3
+)
+{
+.reg .pred %p<3>;
+.reg .f32 %f<4>;
+.reg .b32 %r<7>;
+.reg .b64 %rd<13>;
+
+
+.loc 1 33 1
+func_begin6:
+.loc 1 0 0
+
+.loc 1 33 1
+
+ld.param.u64 %rd1, [_Z9vectorAddPKfS0_Pfi_param_0];
+ld.param.u64 %rd2, [_Z9vectorAddPKfS0_Pfi_param_1];
+ld.param.u64 %rd3, [_Z9vectorAddPKfS0_Pfi_param_2];
+ld.param.u32 %r2, [_Z9vectorAddPKfS0_Pfi_param_3];
+func_exec_begin6:
+.loc 1 35 11
+tmp12:
+mov.u32 %r3, %ntid.x;
+mov.u32 %r4, %ctaid.x;
+mul.lo.s32 %r5, %r3, %r4;
+mov.u32 %r6, %tid.x;
+add.s32 %r1, %r5, %r6;
+tmp13:
+.loc 1 37 5
+setp.lt.s32 %p1, %r1, %r2;
+not.pred %p2, %p1;
+@%p2 bra BB6_2;
+bra.uni BB6_1;
+
+BB6_1:
+.loc 1 39 9
+tmp14:
+cvt.s64.s32 %rd4, %r1;
+shl.b64 %rd5, %rd4, 2;
+add.s64 %rd6, %rd1, %rd5;
+ld.f32 %f1, [%rd6];
+cvt.s64.s32 %rd7, %r1;
+shl.b64 %rd8, %rd7, 2;
+add.s64 %rd9, %rd2, %rd8;
+ld.f32 %f2, [%rd9];
+add.f32 %f3, %f1, %f2;
+cvt.s64.s32 %rd10, %r1;
+shl.b64 %rd11, %rd10, 2;
+add.s64 %rd12, %rd3, %rd11;
+st.f32 [%rd12], %f3;
+tmp15:
+
+BB6_2:
+.loc 1 41 1
+ret;
+tmp16:
+func_end6:
+}
+
+
+.visible .func _ZN4dim3C1Ejjj(
+.param .b64 _ZN4dim3C1Ejjj_param_0,
+.param .b32 _ZN4dim3C1Ejjj_param_1,
+.param .b32 _ZN4dim3C1Ejjj_param_2,
+.param .b32 _ZN4dim3C1Ejjj_param_3
+)
+{
+.reg .b32 %r<4>;
+.reg .b64 %rd<2>;
+
+
+.loc 3 421 1
+func_begin7:
+.loc 3 0 0
+
+.loc 3 421 1
+
+ld.param.u64 %rd1, [_ZN4dim3C1Ejjj_param_0];
+ld.param.u32 %r1, [_ZN4dim3C1Ejjj_param_1];
+ld.param.u32 %r2, [_ZN4dim3C1Ejjj_param_2];
+ld.param.u32 %r3, [_ZN4dim3C1Ejjj_param_3];
+func_exec_begin7:
+.loc 3 421 131
+tmp17:
+st.u32 [%rd1], %r1;
+.loc 3 421 138
+st.u32 [%rd1+4], %r2;
+.loc 3 421 145
+st.u32 [%rd1+8], %r3;
+.loc 3 421 152
+ret;
+tmp18:
+func_end7:
+}
+
+
+.visible .func _ZN4dim3C2Ejjj(
+.param .b64 _ZN4dim3C2Ejjj_param_0,
+.param .b32 _ZN4dim3C2Ejjj_param_1,
+.param .b32 _ZN4dim3C2Ejjj_param_2,
+.param .b32 _ZN4dim3C2Ejjj_param_3
+)
+{
+.reg .b32 %r<4>;
+.reg .b64 %rd<2>;
+
+
+.loc 3 421 1
+func_begin8:
+.loc 3 0 0
+
+.loc 3 421 1
+
+ld.param.u64 %rd1, [_ZN4dim3C2Ejjj_param_0];
+ld.param.u32 %r1, [_ZN4dim3C2Ejjj_param_1];
+ld.param.u32 %r2, [_ZN4dim3C2Ejjj_param_2];
+ld.param.u32 %r3, [_ZN4dim3C2Ejjj_param_3];
+func_exec_begin8:
+.loc 3 421 152
+tmp19:
+
+ {
+.reg .b32 temp_param_reg;
+
+ .param .b64 param0;
+st.param.b64 [param0+0], %rd1;
+.param .b32 param1;
+st.param.b32 [param1+0], %r1;
+.param .b32 param2;
+st.param.b32 [param2+0], %r2;
+.param .b32 param3;
+st.param.b32 [param3+0], %r3;
+call.uni
+_ZN4dim3C1Ejjj,
+(
+param0,
+param1,
+param2,
+param3
+);
+
+
+ }
+ ret;
+tmp20:
+func_end8:
+}
+
+
+.visible .func (.param .b32 func_retval0) _ZSt4fabsf(
+.param .b32 _ZSt4fabsf_param_0
+)
+{
+.reg .f32 %f<3>;
+
+
+.loc 4 241 1
+func_begin9:
+.loc 4 0 0
+
+.loc 4 241 1
+
+ld.param.f32 %f1, [_ZSt4fabsf_param_0];
+func_exec_begin9:
+.loc 4 242 12
+tmp21:
+
+ {
+.reg .b32 temp_param_reg;
+
+ .param .b32 param0;
+st.param.f32 [param0+0], %f1;
+.param .b32 retval0;
+call.uni (retval0),
+fabsf,
+(
+param0
+);
+ld.param.f32 %f2, [retval0+0];
+
+
+ }
+ st.param.f32 [func_retval0+0], %f2;
+ret;
+tmp22:
+func_end9:
+}
+
+.func (.param .b32 func_retval0) fabsf(
+.param .b32 fabsf_param_0
+)
+{
+.reg .f32 %f<3>;
+
+
+ld.param.f32 %f1, [fabsf_param_0];
+abs.f32 %f2, %f1;
+st.param.f32 [func_retval0+0], %f2;
+ret;
+}
+
+.file 1 "/home/vosen/cuda-samples-dbg/0_Simple/vectorAdd/vectorAdd.cu", 1595524614, 5649
+.file 2 "/usr/local/cuda-11.0/bin/../targets/x86_64-linux/include/cuda_device_runtime_api.h", 1595526477, 14970
+.file 3 "/usr/local/cuda-11.0/bin/../targets/x86_64-linux/include/vector_types.h", 1595526477, 13174
+.file 4 "/usr/include/c++/9/cmath", 1586428689, 49130
+.file 5 "/usr/local/cuda-11.0/bin/../targets/x86_64-linux/include/driver_types.h", 1595526477, 105017
+
+.section .debug_info {
+.b32 8837
+.b8 2
+.b8 0
+.b32 .debug_abbrev
+.b8 8
+.b8 1
+
+.b8 108
+.b8 103
+.b8 101
+.b8 110
+.b8 102
+.b8 101
+.b8 58
+.b8 32
+.b8 69
+.b8 68
+.b8 71
+.b8 32
+.b8 53
+.b8 46
+.b8 49
+
+.b8 0
+.b8 4
+.b8 118
+.b8 101
+.b8 99
+.b8 116
+.b8 111
+.b8 114
+.b8 65
+.b8 100
+.b8 100
+.b8 46
+.b8 99
+.b8 117
+
+.b8 0
+.b64 0
+.b32 .debug_line
+.b8 47
+.b8 104
+.b8 111
+.b8 109
+.b8 101
+.b8 47
+.b8 118
+.b8 111
+.b8 115
+.b8 101
+.b8 110
+.b8 47
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 45
+.b8 115
+.b8 97
+.b8 109
+.b8 112
+.b8 108
+.b8 101
+.b8 115
+.b8 45
+.b8 100
+.b8 98
+.b8 103
+.b8 47
+.b8 48
+.b8 95
+.b8 83
+.b8 105
+.b8 109
+.b8 112
+.b8 108
+.b8 101
+.b8 47
+.b8 118
+.b8 101
+.b8 99
+.b8 116
+.b8 111
+.b8 114
+.b8 65
+.b8 100
+.b8 100
+
+.b8 0
+.b8 2
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 77
+.b8 97
+.b8 108
+.b8 108
+.b8 111
+.b8 99
+
+.b8 0
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 77
+.b8 97
+.b8 108
+.b8 108
+.b8 111
+.b8 99
+
+.b8 0
+.b8 2
+.b8 75
+.b32 190
+.b8 1
+.b64 func_begin0
+.b64 func_end0
+.b8 1
+.b8 156
+.b8 3
+
+.b8 112
+
+.b8 0
+.b8 2
+.b8 75
+.b32 8777
+.b8 11
+.b8 3
+.b64 __local_depot0
+.b8 35
+.b8 0
+
+.b8 6
+.b8 3
+
+.b8 115
+
+.b8 0
+.b8 2
+.b8 75
+.b32 8394
+.b8 6
+.b8 144
+.b8 180
+.b8 200
+.b8 201
+.b8 171
+.b8 2
+.b8 2
+.b8 0
+.b8 4
+
+.b32 207
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 95
+.b8 116
+
+.b8 0
+.b8 5
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+
+.b8 0
+.b8 4
+.b8 2
+.b8 189
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 83
+.b8 117
+.b8 99
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+
+.b8 0
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 86
+.b8 97
+.b8 108
+.b8 117
+.b8 101
+
+.b8 0
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 77
+.b8 101
+.b8 109
+.b8 111
+.b8 114
+.b8 121
+.b8 65
+.b8 108
+.b8 108
+.b8 111
+.b8 99
+.b8 97
+.b8 116
+.b8 105
+.b8 111
+.b8 110
+
+.b8 0
+.b8 2
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 105
+.b8 116
+.b8 105
+.b8 97
+.b8 108
+.b8 105
+.b8 122
+.b8 97
+.b8 116
+.b8 105
+.b8 111
+.b8 110
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+
+.b8 0
+.b8 3
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 67
+.b8 117
+.b8 100
+.b8 97
+.b8 114
+.b8 116
+.b8 85
+.b8 110
+.b8 108
+.b8 111
+.b8 97
+.b8 100
+.b8 105
+.b8 110
+.b8 103
+
+.b8 0
+.b8 4
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 80
+.b8 114
+.b8 111
+.b8 102
+.b8 105
+.b8 108
+.b8 101
+.b8 114
+.b8 68
+.b8 105
+.b8 115
+.b8 97
+.b8 98
+.b8 108
+.b8 101
+.b8 100
+
+.b8 0
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 80
+.b8 114
+.b8 111
+.b8 102
+.b8 105
+.b8 108
+.b8 101
+.b8 114
+.b8 78
+.b8 111
+.b8 116
+.b8 73
+.b8 110
+.b8 105
+.b8 116
+.b8 105
+.b8 97
+.b8 108
+.b8 105
+.b8 122
+.b8 101
+.b8 100
+
+.b8 0
+.b8 6
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 80
+.b8 114
+.b8 111
+.b8 102
+.b8 105
+.b8 108
+.b8 101
+.b8 114
+.b8 65
+.b8 108
+.b8 114
+.b8 101
+.b8 97
+.b8 100
+.b8 121
+.b8 83
+.b8 116
+.b8 97
+.b8 114
+.b8 116
+.b8 101
+.b8 100
+
+.b8 0
+.b8 7
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 80
+.b8 114
+.b8 111
+.b8 102
+.b8 105
+.b8 108
+.b8 101
+.b8 114
+.b8 65
+.b8 108
+.b8 114
+.b8 101
+.b8 97
+.b8 100
+.b8 121
+.b8 83
+.b8 116
+.b8 111
+.b8 112
+.b8 112
+.b8 101
+.b8 100
+
+.b8 0
+.b8 8
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 67
+.b8 111
+.b8 110
+.b8 102
+.b8 105
+.b8 103
+.b8 117
+.b8 114
+.b8 97
+.b8 116
+.b8 105
+.b8 111
+.b8 110
+
+.b8 0
+.b8 9
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 80
+.b8 105
+.b8 116
+.b8 99
+.b8 104
+.b8 86
+.b8 97
+.b8 108
+.b8 117
+.b8 101
+
+.b8 0
+.b8 12
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 83
+.b8 121
+.b8 109
+.b8 98
+.b8 111
+.b8 108
+
+.b8 0
+.b8 13
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 72
+.b8 111
+.b8 115
+.b8 116
+.b8 80
+.b8 111
+.b8 105
+.b8 110
+.b8 116
+.b8 101
+.b8 114
+
+.b8 0
+.b8 16
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+.b8 80
+.b8 111
+.b8 105
+.b8 110
+.b8 116
+.b8 101
+.b8 114
+
+.b8 0
+.b8 17
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+
+.b8 0
+.b8 18
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 66
+.b8 105
+.b8 110
+.b8 100
+.b8 105
+.b8 110
+.b8 103
+
+.b8 0
+.b8 19
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 67
+.b8 104
+.b8 97
+.b8 110
+.b8 110
+.b8 101
+.b8 108
+.b8 68
+.b8 101
+.b8 115
+.b8 99
+.b8 114
+.b8 105
+.b8 112
+.b8 116
+.b8 111
+.b8 114
+
+.b8 0
+.b8 20
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 77
+.b8 101
+.b8 109
+.b8 99
+.b8 112
+.b8 121
+.b8 68
+.b8 105
+.b8 114
+.b8 101
+.b8 99
+.b8 116
+.b8 105
+.b8 111
+.b8 110
+
+.b8 0
+.b8 21
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 65
+.b8 100
+.b8 100
+.b8 114
+.b8 101
+.b8 115
+.b8 115
+.b8 79
+.b8 102
+.b8 67
+.b8 111
+.b8 110
+.b8 115
+.b8 116
+.b8 97
+.b8 110
+.b8 116
+
+.b8 0
+.b8 22
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 70
+.b8 101
+.b8 116
+.b8 99
+.b8 104
+.b8 70
+.b8 97
+.b8 105
+.b8 108
+.b8 101
+.b8 100
+
+.b8 0
+.b8 23
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 78
+.b8 111
+.b8 116
+.b8 66
+.b8 111
+.b8 117
+.b8 110
+.b8 100
+
+.b8 0
+.b8 24
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 83
+.b8 121
+.b8 110
+.b8 99
+.b8 104
+.b8 114
+.b8 111
+.b8 110
+.b8 105
+.b8 122
+.b8 97
+.b8 116
+.b8 105
+.b8 111
+.b8 110
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+
+.b8 0
+.b8 25
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 70
+.b8 105
+.b8 108
+.b8 116
+.b8 101
+.b8 114
+.b8 83
+.b8 101
+.b8 116
+.b8 116
+.b8 105
+.b8 110
+.b8 103
+
+.b8 0
+.b8 26
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 78
+.b8 111
+.b8 114
+.b8 109
+.b8 83
+.b8 101
+.b8 116
+.b8 116
+.b8 105
+.b8 110
+.b8 103
+
+.b8 0
+.b8 27
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 77
+.b8 105
+.b8 120
+.b8 101
+.b8 100
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+.b8 69
+.b8 120
+.b8 101
+.b8 99
+.b8 117
+.b8 116
+.b8 105
+.b8 111
+.b8 110
+
+.b8 0
+.b8 28
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 78
+.b8 111
+.b8 116
+.b8 89
+.b8 101
+.b8 116
+.b8 73
+.b8 109
+.b8 112
+.b8 108
+.b8 101
+.b8 109
+.b8 101
+.b8 110
+.b8 116
+.b8 101
+.b8 100
+
+.b8 0
+.b8 31
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 77
+.b8 101
+.b8 109
+.b8 111
+.b8 114
+.b8 121
+.b8 86
+.b8 97
+.b8 108
+.b8 117
+.b8 101
+.b8 84
+.b8 111
+.b8 111
+.b8 76
+.b8 97
+.b8 114
+.b8 103
+.b8 101
+
+.b8 0
+.b8 32
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 115
+.b8 117
+.b8 102
+.b8 102
+.b8 105
+.b8 99
+.b8 105
+.b8 101
+.b8 110
+.b8 116
+.b8 68
+.b8 114
+.b8 105
+.b8 118
+.b8 101
+.b8 114
+
+.b8 0
+.b8 35
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 83
+.b8 117
+.b8 114
+.b8 102
+.b8 97
+.b8 99
+.b8 101
+
+.b8 0
+.b8 37
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 68
+.b8 117
+.b8 112
+.b8 108
+.b8 105
+.b8 99
+.b8 97
+.b8 116
+.b8 101
+.b8 86
+.b8 97
+.b8 114
+.b8 105
+.b8 97
+.b8 98
+.b8 108
+.b8 101
+.b8 78
+.b8 97
+.b8 109
+.b8 101
+
+.b8 0
+.b8 43
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 68
+.b8 117
+.b8 112
+.b8 108
+.b8 105
+.b8 99
+.b8 97
+.b8 116
+.b8 101
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 78
+.b8 97
+.b8 109
+.b8 101
+
+.b8 0
+.b8 44
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 68
+.b8 117
+.b8 112
+.b8 108
+.b8 105
+.b8 99
+.b8 97
+.b8 116
+.b8 101
+.b8 83
+.b8 117
+.b8 114
+.b8 102
+.b8 97
+.b8 99
+.b8 101
+.b8 78
+.b8 97
+.b8 109
+.b8 101
+
+.b8 0
+.b8 45
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+.b8 115
+.b8 85
+.b8 110
+.b8 97
+.b8 118
+.b8 97
+.b8 105
+.b8 108
+.b8 97
+.b8 98
+.b8 108
+.b8 101
+
+.b8 0
+.b8 46
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 99
+.b8 111
+.b8 109
+.b8 112
+.b8 97
+.b8 116
+.b8 105
+.b8 98
+.b8 108
+.b8 101
+.b8 68
+.b8 114
+.b8 105
+.b8 118
+.b8 101
+.b8 114
+.b8 67
+.b8 111
+.b8 110
+.b8 116
+.b8 101
+.b8 120
+.b8 116
+
+.b8 0
+.b8 49
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 77
+.b8 105
+.b8 115
+.b8 115
+.b8 105
+.b8 110
+.b8 103
+.b8 67
+.b8 111
+.b8 110
+.b8 102
+.b8 105
+.b8 103
+.b8 117
+.b8 114
+.b8 97
+.b8 116
+.b8 105
+.b8 111
+.b8 110
+
+.b8 0
+.b8 52
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 80
+.b8 114
+.b8 105
+.b8 111
+.b8 114
+.b8 76
+.b8 97
+.b8 117
+.b8 110
+.b8 99
+.b8 104
+.b8 70
+.b8 97
+.b8 105
+.b8 108
+.b8 117
+.b8 114
+.b8 101
+
+.b8 0
+.b8 53
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 76
+.b8 97
+.b8 117
+.b8 110
+.b8 99
+.b8 104
+.b8 77
+.b8 97
+.b8 120
+.b8 68
+.b8 101
+.b8 112
+.b8 116
+.b8 104
+.b8 69
+.b8 120
+.b8 99
+.b8 101
+.b8 101
+.b8 100
+.b8 101
+.b8 100
+
+.b8 0
+.b8 193
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 76
+.b8 97
+.b8 117
+.b8 110
+.b8 99
+.b8 104
+.b8 70
+.b8 105
+.b8 108
+.b8 101
+.b8 83
+.b8 99
+.b8 111
+.b8 112
+.b8 101
+.b8 100
+.b8 84
+.b8 101
+.b8 120
+
+.b8 0
+.b8 194
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 76
+.b8 97
+.b8 117
+.b8 110
+.b8 99
+.b8 104
+.b8 70
+.b8 105
+.b8 108
+.b8 101
+.b8 83
+.b8 99
+.b8 111
+.b8 112
+.b8 101
+.b8 100
+.b8 83
+.b8 117
+.b8 114
+.b8 102
+
+.b8 0
+.b8 195
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 83
+.b8 121
+.b8 110
+.b8 99
+.b8 68
+.b8 101
+.b8 112
+.b8 116
+.b8 104
+.b8 69
+.b8 120
+.b8 99
+.b8 101
+.b8 101
+.b8 100
+.b8 101
+.b8 100
+
+.b8 0
+.b8 196
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 76
+.b8 97
+.b8 117
+.b8 110
+.b8 99
+.b8 104
+.b8 80
+.b8 101
+.b8 110
+.b8 100
+.b8 105
+.b8 110
+.b8 103
+.b8 67
+.b8 111
+.b8 117
+.b8 110
+.b8 116
+.b8 69
+.b8 120
+.b8 99
+.b8 101
+.b8 101
+.b8 100
+.b8 101
+.b8 100
+
+.b8 0
+.b8 197
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+.b8 70
+.b8 117
+.b8 110
+.b8 99
+.b8 116
+.b8 105
+.b8 111
+.b8 110
+
+.b8 0
+.b8 226
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 78
+.b8 111
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+
+.b8 0
+.b8 228
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+
+.b8 0
+.b8 229
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 83
+.b8 116
+.b8 97
+.b8 114
+.b8 116
+.b8 117
+.b8 112
+.b8 70
+.b8 97
+.b8 105
+.b8 108
+.b8 117
+.b8 114
+.b8 101
+
+.b8 0
+.b8 255
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 75
+.b8 101
+.b8 114
+.b8 110
+.b8 101
+.b8 108
+.b8 73
+.b8 109
+.b8 97
+.b8 103
+.b8 101
+
+.b8 0
+.b8 200
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+.b8 85
+.b8 110
+.b8 105
+.b8 110
+.b8 105
+.b8 116
+.b8 105
+.b8 97
+.b8 108
+.b8 105
+.b8 122
+.b8 101
+.b8 100
+
+.b8 0
+.b8 201
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 77
+.b8 97
+.b8 112
+.b8 66
+.b8 117
+.b8 102
+.b8 102
+.b8 101
+.b8 114
+.b8 79
+.b8 98
+.b8 106
+.b8 101
+.b8 99
+.b8 116
+.b8 70
+.b8 97
+.b8 105
+.b8 108
+.b8 101
+.b8 100
+
+.b8 0
+.b8 205
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 85
+.b8 110
+.b8 109
+.b8 97
+.b8 112
+.b8 66
+.b8 117
+.b8 102
+.b8 102
+.b8 101
+.b8 114
+.b8 79
+.b8 98
+.b8 106
+.b8 101
+.b8 99
+.b8 116
+.b8 70
+.b8 97
+.b8 105
+.b8 108
+.b8 101
+.b8 100
+
+.b8 0
+.b8 206
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 65
+.b8 114
+.b8 114
+.b8 97
+.b8 121
+.b8 73
+.b8 115
+.b8 77
+.b8 97
+.b8 112
+.b8 112
+.b8 101
+.b8 100
+
+.b8 0
+.b8 207
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 65
+.b8 108
+.b8 114
+.b8 101
+.b8 97
+.b8 100
+.b8 121
+.b8 77
+.b8 97
+.b8 112
+.b8 112
+.b8 101
+.b8 100
+
+.b8 0
+.b8 208
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 78
+.b8 111
+.b8 75
+.b8 101
+.b8 114
+.b8 110
+.b8 101
+.b8 108
+.b8 73
+.b8 109
+.b8 97
+.b8 103
+.b8 101
+.b8 70
+.b8 111
+.b8 114
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+
+.b8 0
+.b8 209
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 65
+.b8 108
+.b8 114
+.b8 101
+.b8 97
+.b8 100
+.b8 121
+.b8 65
+.b8 99
+.b8 113
+.b8 117
+.b8 105
+.b8 114
+.b8 101
+.b8 100
+
+.b8 0
+.b8 210
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 78
+.b8 111
+.b8 116
+.b8 77
+.b8 97
+.b8 112
+.b8 112
+.b8 101
+.b8 100
+
+.b8 0
+.b8 211
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 78
+.b8 111
+.b8 116
+.b8 77
+.b8 97
+.b8 112
+.b8 112
+.b8 101
+.b8 100
+.b8 65
+.b8 115
+.b8 65
+.b8 114
+.b8 114
+.b8 97
+.b8 121
+
+.b8 0
+.b8 212
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 78
+.b8 111
+.b8 116
+.b8 77
+.b8 97
+.b8 112
+.b8 112
+.b8 101
+.b8 100
+.b8 65
+.b8 115
+.b8 80
+.b8 111
+.b8 105
+.b8 110
+.b8 116
+.b8 101
+.b8 114
+
+.b8 0
+.b8 213
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 69
+.b8 67
+.b8 67
+.b8 85
+.b8 110
+.b8 99
+.b8 111
+.b8 114
+.b8 114
+.b8 101
+.b8 99
+.b8 116
+.b8 97
+.b8 98
+.b8 108
+.b8 101
+
+.b8 0
+.b8 214
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 85
+.b8 110
+.b8 115
+.b8 117
+.b8 112
+.b8 112
+.b8 111
+.b8 114
+.b8 116
+.b8 101
+.b8 100
+.b8 76
+.b8 105
+.b8 109
+.b8 105
+.b8 116
+
+.b8 0
+.b8 215
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+.b8 65
+.b8 108
+.b8 114
+.b8 101
+.b8 97
+.b8 100
+.b8 121
+.b8 73
+.b8 110
+.b8 85
+.b8 115
+.b8 101
+
+.b8 0
+.b8 216
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 80
+.b8 101
+.b8 101
+.b8 114
+.b8 65
+.b8 99
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+.b8 85
+.b8 110
+.b8 115
+.b8 117
+.b8 112
+.b8 112
+.b8 111
+.b8 114
+.b8 116
+.b8 101
+.b8 100
+
+.b8 0
+.b8 217
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 80
+.b8 116
+.b8 120
+
+.b8 0
+.b8 218
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 71
+.b8 114
+.b8 97
+.b8 112
+.b8 104
+.b8 105
+.b8 99
+.b8 115
+.b8 67
+.b8 111
+.b8 110
+.b8 116
+.b8 101
+.b8 120
+.b8 116
+
+.b8 0
+.b8 219
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 78
+.b8 118
+.b8 108
+.b8 105
+.b8 110
+.b8 107
+.b8 85
+.b8 110
+.b8 99
+.b8 111
+.b8 114
+.b8 114
+.b8 101
+.b8 99
+.b8 116
+.b8 97
+.b8 98
+.b8 108
+.b8 101
+
+.b8 0
+.b8 220
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 74
+.b8 105
+.b8 116
+.b8 67
+.b8 111
+.b8 109
+.b8 112
+.b8 105
+.b8 108
+.b8 101
+.b8 114
+.b8 78
+.b8 111
+.b8 116
+.b8 70
+.b8 111
+.b8 117
+.b8 110
+.b8 100
+
+.b8 0
+.b8 221
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 83
+.b8 111
+.b8 117
+.b8 114
+.b8 99
+.b8 101
+
+.b8 0
+.b8 172
+.b8 2
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 70
+.b8 105
+.b8 108
+.b8 101
+.b8 78
+.b8 111
+.b8 116
+.b8 70
+.b8 111
+.b8 117
+.b8 110
+.b8 100
+
+.b8 0
+.b8 173
+.b8 2
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 83
+.b8 104
+.b8 97
+.b8 114
+.b8 101
+.b8 100
+.b8 79
+.b8 98
+.b8 106
+.b8 101
+.b8 99
+.b8 116
+.b8 83
+.b8 121
+.b8 109
+.b8 98
+.b8 111
+.b8 108
+.b8 78
+.b8 111
+.b8 116
+.b8 70
+.b8 111
+.b8 117
+.b8 110
+.b8 100
+
+.b8 0
+.b8 174
+.b8 2
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 83
+.b8 104
+.b8 97
+.b8 114
+.b8 101
+.b8 100
+.b8 79
+.b8 98
+.b8 106
+.b8 101
+.b8 99
+.b8 116
+.b8 73
+.b8 110
+.b8 105
+.b8 116
+.b8 70
+.b8 97
+.b8 105
+.b8 108
+.b8 101
+.b8 100
+
+.b8 0
+.b8 175
+.b8 2
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 79
+.b8 112
+.b8 101
+.b8 114
+.b8 97
+.b8 116
+.b8 105
+.b8 110
+.b8 103
+.b8 83
+.b8 121
+.b8 115
+.b8 116
+.b8 101
+.b8 109
+
+.b8 0
+.b8 176
+.b8 2
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 82
+.b8 101
+.b8 115
+.b8 111
+.b8 117
+.b8 114
+.b8 99
+.b8 101
+.b8 72
+.b8 97
+.b8 110
+.b8 100
+.b8 108
+.b8 101
+
+.b8 0
+.b8 144
+.b8 3
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 108
+.b8 108
+.b8 101
+.b8 103
+.b8 97
+.b8 108
+.b8 83
+.b8 116
+.b8 97
+.b8 116
+.b8 101
+
+.b8 0
+.b8 145
+.b8 3
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 83
+.b8 121
+.b8 109
+.b8 98
+.b8 111
+.b8 108
+.b8 78
+.b8 111
+.b8 116
+.b8 70
+.b8 111
+.b8 117
+.b8 110
+.b8 100
+
+.b8 0
+.b8 244
+.b8 3
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 78
+.b8 111
+.b8 116
+.b8 82
+.b8 101
+.b8 97
+.b8 100
+.b8 121
+
+.b8 0
+.b8 216
+.b8 4
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 108
+.b8 108
+.b8 101
+.b8 103
+.b8 97
+.b8 108
+.b8 65
+.b8 100
+.b8 100
+.b8 114
+.b8 101
+.b8 115
+.b8 115
+
+.b8 0
+.b8 188
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 76
+.b8 97
+.b8 117
+.b8 110
+.b8 99
+.b8 104
+.b8 79
+.b8 117
+.b8 116
+.b8 79
+.b8 102
+.b8 82
+.b8 101
+.b8 115
+.b8 111
+.b8 117
+.b8 114
+.b8 99
+.b8 101
+.b8 115
+
+.b8 0
+.b8 189
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 76
+.b8 97
+.b8 117
+.b8 110
+.b8 99
+.b8 104
+.b8 84
+.b8 105
+.b8 109
+.b8 101
+.b8 111
+.b8 117
+.b8 116
+
+.b8 0
+.b8 190
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 76
+.b8 97
+.b8 117
+.b8 110
+.b8 99
+.b8 104
+.b8 73
+.b8 110
+.b8 99
+.b8 111
+.b8 109
+.b8 112
+.b8 97
+.b8 116
+.b8 105
+.b8 98
+.b8 108
+.b8 101
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 105
+.b8 110
+.b8 103
+
+.b8 0
+.b8 191
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 80
+.b8 101
+.b8 101
+.b8 114
+.b8 65
+.b8 99
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+.b8 65
+.b8 108
+.b8 114
+.b8 101
+.b8 97
+.b8 100
+.b8 121
+.b8 69
+.b8 110
+.b8 97
+.b8 98
+.b8 108
+.b8 101
+.b8 100
+
+.b8 0
+.b8 192
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 80
+.b8 101
+.b8 101
+.b8 114
+.b8 65
+.b8 99
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+.b8 78
+.b8 111
+.b8 116
+.b8 69
+.b8 110
+.b8 97
+.b8 98
+.b8 108
+.b8 101
+.b8 100
+
+.b8 0
+.b8 193
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 83
+.b8 101
+.b8 116
+.b8 79
+.b8 110
+.b8 65
+.b8 99
+.b8 116
+.b8 105
+.b8 118
+.b8 101
+.b8 80
+.b8 114
+.b8 111
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+
+.b8 0
+.b8 196
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 67
+.b8 111
+.b8 110
+.b8 116
+.b8 101
+.b8 120
+.b8 116
+.b8 73
+.b8 115
+.b8 68
+.b8 101
+.b8 115
+.b8 116
+.b8 114
+.b8 111
+.b8 121
+.b8 101
+.b8 100
+
+.b8 0
+.b8 197
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 65
+.b8 115
+.b8 115
+.b8 101
+.b8 114
+.b8 116
+
+.b8 0
+.b8 198
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 84
+.b8 111
+.b8 111
+.b8 77
+.b8 97
+.b8 110
+.b8 121
+.b8 80
+.b8 101
+.b8 101
+.b8 114
+.b8 115
+
+.b8 0
+.b8 199
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 72
+.b8 111
+.b8 115
+.b8 116
+.b8 77
+.b8 101
+.b8 109
+.b8 111
+.b8 114
+.b8 121
+.b8 65
+.b8 108
+.b8 114
+.b8 101
+.b8 97
+.b8 100
+.b8 121
+.b8 82
+.b8 101
+.b8 103
+.b8 105
+.b8 115
+.b8 116
+.b8 101
+.b8 114
+.b8 101
+.b8 100
+
+.b8 0
+.b8 200
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 72
+.b8 111
+.b8 115
+.b8 116
+.b8 77
+.b8 101
+.b8 109
+.b8 111
+.b8 114
+.b8 121
+.b8 78
+.b8 111
+.b8 116
+.b8 82
+.b8 101
+.b8 103
+.b8 105
+.b8 115
+.b8 116
+.b8 101
+.b8 114
+.b8 101
+.b8 100
+
+.b8 0
+.b8 201
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 72
+.b8 97
+.b8 114
+.b8 100
+.b8 119
+.b8 97
+.b8 114
+.b8 101
+.b8 83
+.b8 116
+.b8 97
+.b8 99
+.b8 107
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+
+.b8 0
+.b8 202
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 108
+.b8 108
+.b8 101
+.b8 103
+.b8 97
+.b8 108
+.b8 73
+.b8 110
+.b8 115
+.b8 116
+.b8 114
+.b8 117
+.b8 99
+.b8 116
+.b8 105
+.b8 111
+.b8 110
+
+.b8 0
+.b8 203
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 77
+.b8 105
+.b8 115
+.b8 97
+.b8 108
+.b8 105
+.b8 103
+.b8 110
+.b8 101
+.b8 100
+.b8 65
+.b8 100
+.b8 100
+.b8 114
+.b8 101
+.b8 115
+.b8 115
+
+.b8 0
+.b8 204
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 65
+.b8 100
+.b8 100
+.b8 114
+.b8 101
+.b8 115
+.b8 115
+.b8 83
+.b8 112
+.b8 97
+.b8 99
+.b8 101
+
+.b8 0
+.b8 205
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 80
+.b8 99
+
+.b8 0
+.b8 206
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 76
+.b8 97
+.b8 117
+.b8 110
+.b8 99
+.b8 104
+.b8 70
+.b8 97
+.b8 105
+.b8 108
+.b8 117
+.b8 114
+.b8 101
+
+.b8 0
+.b8 207
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 67
+.b8 111
+.b8 111
+.b8 112
+.b8 101
+.b8 114
+.b8 97
+.b8 116
+.b8 105
+.b8 118
+.b8 101
+.b8 76
+.b8 97
+.b8 117
+.b8 110
+.b8 99
+.b8 104
+.b8 84
+.b8 111
+.b8 111
+.b8 76
+.b8 97
+.b8 114
+.b8 103
+.b8 101
+
+.b8 0
+.b8 208
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 78
+.b8 111
+.b8 116
+.b8 80
+.b8 101
+.b8 114
+.b8 109
+.b8 105
+.b8 116
+.b8 116
+.b8 101
+.b8 100
+
+.b8 0
+.b8 160
+.b8 6
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 78
+.b8 111
+.b8 116
+.b8 83
+.b8 117
+.b8 112
+.b8 112
+.b8 111
+.b8 114
+.b8 116
+.b8 101
+.b8 100
+
+.b8 0
+.b8 161
+.b8 6
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 83
+.b8 121
+.b8 115
+.b8 116
+.b8 101
+.b8 109
+.b8 78
+.b8 111
+.b8 116
+.b8 82
+.b8 101
+.b8 97
+.b8 100
+.b8 121
+
+.b8 0
+.b8 162
+.b8 6
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 83
+.b8 121
+.b8 115
+.b8 116
+.b8 101
+.b8 109
+.b8 68
+.b8 114
+.b8 105
+.b8 118
+.b8 101
+.b8 114
+.b8 77
+.b8 105
+.b8 115
+.b8 109
+.b8 97
+.b8 116
+.b8 99
+.b8 104
+
+.b8 0
+.b8 163
+.b8 6
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 67
+.b8 111
+.b8 109
+.b8 112
+.b8 97
+.b8 116
+.b8 78
+.b8 111
+.b8 116
+.b8 83
+.b8 117
+.b8 112
+.b8 112
+.b8 111
+.b8 114
+.b8 116
+.b8 101
+.b8 100
+.b8 79
+.b8 110
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+
+.b8 0
+.b8 164
+.b8 6
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 83
+.b8 116
+.b8 114
+.b8 101
+.b8 97
+.b8 109
+.b8 67
+.b8 97
+.b8 112
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 85
+.b8 110
+.b8 115
+.b8 117
+.b8 112
+.b8 112
+.b8 111
+.b8 114
+.b8 116
+.b8 101
+.b8 100
+
+.b8 0
+.b8 132
+.b8 7
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 83
+.b8 116
+.b8 114
+.b8 101
+.b8 97
+.b8 109
+.b8 67
+.b8 97
+.b8 112
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 73
+.b8 110
+.b8 118
+.b8 97
+.b8 108
+.b8 105
+.b8 100
+.b8 97
+.b8 116
+.b8 101
+.b8 100
+
+.b8 0
+.b8 133
+.b8 7
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 83
+.b8 116
+.b8 114
+.b8 101
+.b8 97
+.b8 109
+.b8 67
+.b8 97
+.b8 112
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 77
+.b8 101
+.b8 114
+.b8 103
+.b8 101
+
+.b8 0
+.b8 134
+.b8 7
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 83
+.b8 116
+.b8 114
+.b8 101
+.b8 97
+.b8 109
+.b8 67
+.b8 97
+.b8 112
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 85
+.b8 110
+.b8 109
+.b8 97
+.b8 116
+.b8 99
+.b8 104
+.b8 101
+.b8 100
+
+.b8 0
+.b8 135
+.b8 7
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 83
+.b8 116
+.b8 114
+.b8 101
+.b8 97
+.b8 109
+.b8 67
+.b8 97
+.b8 112
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 85
+.b8 110
+.b8 106
+.b8 111
+.b8 105
+.b8 110
+.b8 101
+.b8 100
+
+.b8 0
+.b8 136
+.b8 7
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 83
+.b8 116
+.b8 114
+.b8 101
+.b8 97
+.b8 109
+.b8 67
+.b8 97
+.b8 112
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 73
+.b8 115
+.b8 111
+.b8 108
+.b8 97
+.b8 116
+.b8 105
+.b8 111
+.b8 110
+
+.b8 0
+.b8 137
+.b8 7
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 83
+.b8 116
+.b8 114
+.b8 101
+.b8 97
+.b8 109
+.b8 67
+.b8 97
+.b8 112
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 73
+.b8 109
+.b8 112
+.b8 108
+.b8 105
+.b8 99
+.b8 105
+.b8 116
+
+.b8 0
+.b8 138
+.b8 7
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 67
+.b8 97
+.b8 112
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 100
+.b8 69
+.b8 118
+.b8 101
+.b8 110
+.b8 116
+
+.b8 0
+.b8 139
+.b8 7
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 83
+.b8 116
+.b8 114
+.b8 101
+.b8 97
+.b8 109
+.b8 67
+.b8 97
+.b8 112
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 87
+.b8 114
+.b8 111
+.b8 110
+.b8 103
+.b8 84
+.b8 104
+.b8 114
+.b8 101
+.b8 97
+.b8 100
+
+.b8 0
+.b8 140
+.b8 7
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 84
+.b8 105
+.b8 109
+.b8 101
+.b8 111
+.b8 117
+.b8 116
+
+.b8 0
+.b8 141
+.b8 7
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 71
+.b8 114
+.b8 97
+.b8 112
+.b8 104
+.b8 69
+.b8 120
+.b8 101
+.b8 99
+.b8 85
+.b8 112
+.b8 100
+.b8 97
+.b8 116
+.b8 101
+.b8 70
+.b8 97
+.b8 105
+.b8 108
+.b8 117
+.b8 114
+.b8 101
+
+.b8 0
+.b8 142
+.b8 7
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 85
+.b8 110
+.b8 107
+.b8 110
+.b8 111
+.b8 119
+.b8 110
+
+.b8 0
+.b8 231
+.b8 7
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 69
+.b8 114
+.b8 114
+.b8 111
+.b8 114
+.b8 65
+.b8 112
+.b8 105
+.b8 70
+.b8 97
+.b8 105
+.b8 108
+.b8 117
+.b8 114
+.b8 101
+.b8 66
+.b8 97
+.b8 115
+.b8 101
+
+.b8 0
+.b8 144
+.b8 206
+.b8 0
+
+.b8 0
+.b8 2
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 70
+.b8 117
+.b8 110
+.b8 99
+.b8 71
+.b8 101
+.b8 116
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 105
+.b8 98
+.b8 117
+.b8 116
+.b8 101
+.b8 115
+
+.b8 0
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 70
+.b8 117
+.b8 110
+.b8 99
+.b8 71
+.b8 101
+.b8 116
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 105
+.b8 98
+.b8 117
+.b8 116
+.b8 101
+.b8 115
+
+.b8 0
+.b8 2
+.b8 80
+.b32 190
+.b8 1
+.b64 func_begin1
+.b64 func_end1
+.b8 1
+.b8 156
+.b8 3
+
+.b8 112
+
+.b8 0
+.b8 2
+.b8 80
+.b32 8789
+.b8 11
+.b8 3
+.b64 __local_depot1
+.b8 35
+.b8 0
+
+.b8 6
+.b8 3
+
+.b8 99
+
+.b8 0
+.b8 2
+.b8 80
+.b32 8795
+.b8 6
+.b8 144
+.b8 180
+.b8 200
+.b8 201
+.b8 171
+.b8 2
+.b8 2
+.b8 0
+.b8 2
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+.b8 71
+.b8 101
+.b8 116
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 105
+.b8 98
+.b8 117
+.b8 116
+.b8 101
+
+.b8 0
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+.b8 71
+.b8 101
+.b8 116
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 105
+.b8 98
+.b8 117
+.b8 116
+.b8 101
+
+.b8 0
+.b8 2
+.b8 85
+.b32 190
+.b8 1
+.b64 func_begin2
+.b64 func_end2
+.b8 1
+.b8 156
+.b8 3
+
+.b8 118
+.b8 97
+.b8 108
+.b8 117
+.b8 101
+
+.b8 0
+.b8 2
+.b8 85
+.b32 8806
+.b8 6
+.b8 144
+.b8 178
+.b8 200
+.b8 201
+.b8 171
+.b8 2
+.b8 2
+.b8 3
+
+.b8 97
+.b8 116
+.b8 116
+.b8 114
+
+.b8 0
+.b8 2
+.b8 85
+.b32 4881
+.b8 5
+.b8 144
+.b8 179
+.b8 228
+.b8 149
+.b8 1
+.b8 2
+.b8 3
+
+.b8 100
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+
+.b8 0
+.b8 2
+.b8 85
+.b32 8707
+.b8 5
+.b8 144
+.b8 180
+.b8 228
+.b8 149
+.b8 1
+.b8 2
+.b8 0
+.b8 2
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 71
+.b8 101
+.b8 116
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+
+.b8 0
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 71
+.b8 101
+.b8 116
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+
+.b8 0
+.b8 2
+.b8 90
+.b32 190
+.b8 1
+.b64 func_begin3
+.b64 func_end3
+.b8 1
+.b8 156
+.b8 3
+
+.b8 100
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+
+.b8 0
+.b8 2
+.b8 90
+.b32 8806
+.b8 6
+.b8 144
+.b8 178
+.b8 200
+.b8 201
+.b8 171
+.b8 2
+.b8 2
+.b8 0
+.b8 2
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 79
+.b8 99
+.b8 99
+.b8 117
+.b8 112
+.b8 97
+.b8 110
+.b8 99
+.b8 121
+.b8 77
+.b8 97
+.b8 120
+.b8 65
+.b8 99
+.b8 116
+.b8 105
+.b8 118
+.b8 101
+.b8 66
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+.b8 115
+.b8 80
+.b8 101
+.b8 114
+.b8 77
+.b8 117
+.b8 108
+.b8 116
+.b8 105
+.b8 112
+.b8 114
+.b8 111
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+.b8 111
+.b8 114
+
+.b8 0
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 79
+.b8 99
+.b8 99
+.b8 117
+.b8 112
+.b8 97
+.b8 110
+.b8 99
+.b8 121
+.b8 77
+.b8 97
+.b8 120
+.b8 65
+.b8 99
+.b8 116
+.b8 105
+.b8 118
+.b8 101
+.b8 66
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+.b8 115
+.b8 80
+.b8 101
+.b8 114
+.b8 77
+.b8 117
+.b8 108
+.b8 116
+.b8 105
+.b8 112
+.b8 114
+.b8 111
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+.b8 111
+.b8 114
+
+.b8 0
+.b8 2
+.b8 95
+.b32 190
+.b8 1
+.b64 func_begin4
+.b64 func_end4
+.b8 1
+.b8 156
+.b8 3
+
+.b8 110
+.b8 117
+.b8 109
+.b8 66
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+.b8 115
+
+.b8 0
+.b8 2
+.b8 95
+.b32 8806
+.b8 6
+.b8 144
+.b8 180
+.b8 200
+.b8 201
+.b8 171
+.b8 2
+.b8 2
+.b8 3
+
+.b8 102
+.b8 117
+.b8 110
+.b8 99
+
+.b8 0
+.b8 2
+.b8 95
+.b32 8795
+.b8 6
+.b8 144
+.b8 181
+.b8 200
+.b8 201
+.b8 171
+.b8 2
+.b8 2
+.b8 3
+
+.b8 98
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+.b8 83
+.b8 105
+.b8 122
+.b8 101
+
+.b8 0
+.b8 2
+.b8 95
+.b32 8707
+.b8 5
+.b8 144
+.b8 178
+.b8 228
+.b8 149
+.b8 1
+.b8 2
+.b8 3
+
+.b8 100
+.b8 121
+.b8 110
+.b8 97
+.b8 109
+.b8 105
+.b8 99
+.b8 83
+.b8 109
+.b8 101
+.b8 109
+.b8 83
+.b8 105
+.b8 122
+.b8 101
+
+.b8 0
+.b8 2
+.b8 95
+.b32 8394
+.b8 6
+.b8 144
+.b8 182
+.b8 200
+.b8 201
+.b8 171
+.b8 2
+.b8 2
+.b8 0
+.b8 2
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 79
+.b8 99
+.b8 99
+.b8 117
+.b8 112
+.b8 97
+.b8 110
+.b8 99
+.b8 121
+.b8 77
+.b8 97
+.b8 120
+.b8 65
+.b8 99
+.b8 116
+.b8 105
+.b8 118
+.b8 101
+.b8 66
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+.b8 115
+.b8 80
+.b8 101
+.b8 114
+.b8 77
+.b8 117
+.b8 108
+.b8 116
+.b8 105
+.b8 112
+.b8 114
+.b8 111
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+.b8 111
+.b8 114
+.b8 87
+.b8 105
+.b8 116
+.b8 104
+.b8 70
+.b8 108
+.b8 97
+.b8 103
+.b8 115
+
+.b8 0
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 79
+.b8 99
+.b8 99
+.b8 117
+.b8 112
+.b8 97
+.b8 110
+.b8 99
+.b8 121
+.b8 77
+.b8 97
+.b8 120
+.b8 65
+.b8 99
+.b8 116
+.b8 105
+.b8 118
+.b8 101
+.b8 66
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+.b8 115
+.b8 80
+.b8 101
+.b8 114
+.b8 77
+.b8 117
+.b8 108
+.b8 116
+.b8 105
+.b8 112
+.b8 114
+.b8 111
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+.b8 111
+.b8 114
+.b8 87
+.b8 105
+.b8 116
+.b8 104
+.b8 70
+.b8 108
+.b8 97
+.b8 103
+.b8 115
+
+.b8 0
+.b8 2
+.b8 100
+.b32 190
+.b8 1
+.b64 func_begin5
+.b64 func_end5
+.b8 1
+.b8 156
+.b8 3
+
+.b8 110
+.b8 117
+.b8 109
+.b8 66
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+.b8 115
+
+.b8 0
+.b8 2
+.b8 100
+.b32 8806
+.b8 6
+.b8 144
+.b8 180
+.b8 200
+.b8 201
+.b8 171
+.b8 2
+.b8 2
+.b8 3
+
+.b8 102
+.b8 117
+.b8 110
+.b8 99
+
+.b8 0
+.b8 2
+.b8 100
+.b32 8795
+.b8 6
+.b8 144
+.b8 181
+.b8 200
+.b8 201
+.b8 171
+.b8 2
+.b8 2
+.b8 3
+
+.b8 98
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+.b8 83
+.b8 105
+.b8 122
+.b8 101
+
+.b8 0
+.b8 2
+.b8 100
+.b32 8707
+.b8 5
+.b8 144
+.b8 179
+.b8 228
+.b8 149
+.b8 1
+.b8 2
+.b8 3
+
+.b8 100
+.b8 121
+.b8 110
+.b8 97
+.b8 109
+.b8 105
+.b8 99
+.b8 83
+.b8 109
+.b8 101
+.b8 109
+.b8 83
+.b8 105
+.b8 122
+.b8 101
+
+.b8 0
+.b8 2
+.b8 100
+.b32 8394
+.b8 6
+.b8 144
+.b8 182
+.b8 200
+.b8 201
+.b8 171
+.b8 2
+.b8 2
+.b8 3
+
+.b8 102
+.b8 108
+.b8 97
+.b8 103
+.b8 115
+
+.b8 0
+.b8 2
+.b8 100
+.b32 8761
+.b8 5
+.b8 144
+.b8 180
+.b8 228
+.b8 149
+.b8 1
+.b8 2
+.b8 0
+.b8 2
+
+.b8 95
+.b8 90
+.b8 57
+.b8 118
+.b8 101
+.b8 99
+.b8 116
+.b8 111
+.b8 114
+.b8 65
+.b8 100
+.b8 100
+.b8 80
+.b8 75
+.b8 102
+.b8 83
+.b8 48
+.b8 95
+.b8 80
+.b8 102
+.b8 105
+
+.b8 0
+.b8 95
+.b8 90
+.b8 57
+.b8 118
+.b8 101
+.b8 99
+.b8 116
+.b8 111
+.b8 114
+.b8 65
+.b8 100
+.b8 100
+.b8 80
+.b8 75
+.b8 102
+.b8 83
+.b8 48
+.b8 95
+.b8 80
+.b8 102
+.b8 105
+
+.b8 0
+.b8 1
+.b8 33
+.b32 4557
+.b8 1
+.b64 func_begin6
+.b64 func_end6
+.b8 1
+.b8 156
+.b8 3
+
+.b8 65
+
+.b8 0
+.b8 1
+.b8 33
+.b32 8812
+.b8 9
+.b8 3
+.b64 _Z9vectorAddPKfS0_Pfi_param_0
+.b8 7
+.b8 3
+
+.b8 66
+
+.b8 0
+.b8 1
+.b8 33
+.b32 8812
+.b8 9
+.b8 3
+.b64 _Z9vectorAddPKfS0_Pfi_param_1
+.b8 7
+.b8 3
+
+.b8 67
+
+.b8 0
+.b8 1
+.b8 33
+.b32 8823
+.b8 9
+.b8 3
+.b64 _Z9vectorAddPKfS0_Pfi_param_2
+.b8 7
+.b8 3
+
+.b8 110
+.b8 117
+.b8 109
+.b8 69
+.b8 108
+.b8 101
+.b8 109
+.b8 101
+.b8 110
+.b8 116
+.b8 115
+
+.b8 0
+.b8 1
+.b8 33
+.b32 8707
+.b8 9
+.b8 3
+.b64 _Z9vectorAddPKfS0_Pfi_param_3
+.b8 7
+.b8 7
+
+.b64 tmp12
+.b64 tmp16
+.b8 8
+
+.b8 105
+
+.b8 0
+.b8 1
+.b8 35
+.b32 8707
+.b8 5
+.b8 144
+.b8 177
+.b8 228
+.b8 149
+.b8 1
+.b8 2
+.b8 0
+.b8 0
+.b8 9
+
+.b8 118
+.b8 111
+.b8 105
+.b8 100
+
+.b8 0
+.b8 10
+
+.b8 95
+.b8 90
+.b8 78
+.b8 52
+.b8 100
+.b8 105
+.b8 109
+.b8 51
+.b8 67
+.b8 49
+.b8 69
+.b8 106
+.b8 106
+.b8 106
+
+.b8 0
+.b8 95
+.b8 90
+.b8 78
+.b8 52
+.b8 100
+.b8 105
+.b8 109
+.b8 51
+.b8 67
+.b8 49
+.b8 69
+.b8 106
+.b8 106
+.b8 106
+
+.b8 0
+.b8 3
+.b16 421
+.b32 4557
+.b8 1
+.b64 func_begin7
+.b64 func_end7
+.b8 1
+.b8 156
+.b8 11
+
+.b8 116
+.b8 104
+.b8 105
+.b8 115
+
+.b8 0
+.b32 8829
+.b8 6
+.b8 144
+.b8 177
+.b8 200
+.b8 201
+.b8 171
+.b8 2
+.b8 2
+.b8 12
+
+.b8 118
+.b8 120
+
+.b8 0
+.b8 3
+.b16 421
+.b32 8761
+.b8 5
+.b8 144
+.b8 177
+.b8 228
+.b8 149
+.b8 1
+.b8 2
+.b8 12
+
+.b8 118
+.b8 121
+
+.b8 0
+.b8 3
+.b16 421
+.b32 8761
+.b8 5
+.b8 144
+.b8 178
+.b8 228
+.b8 149
+.b8 1
+.b8 2
+.b8 12
+
+.b8 118
+.b8 122
+
+.b8 0
+.b8 3
+.b16 421
+.b32 8761
+.b8 5
+.b8 144
+.b8 179
+.b8 228
+.b8 149
+.b8 1
+.b8 2
+.b8 0
+.b8 10
+
+.b8 95
+.b8 90
+.b8 78
+.b8 52
+.b8 100
+.b8 105
+.b8 109
+.b8 51
+.b8 67
+.b8 50
+.b8 69
+.b8 106
+.b8 106
+.b8 106
+
+.b8 0
+.b8 95
+.b8 90
+.b8 78
+.b8 52
+.b8 100
+.b8 105
+.b8 109
+.b8 51
+.b8 67
+.b8 50
+.b8 69
+.b8 106
+.b8 106
+.b8 106
+
+.b8 0
+.b8 3
+.b16 421
+.b32 4557
+.b8 1
+.b64 func_begin8
+.b64 func_end8
+.b8 1
+.b8 156
+.b8 11
+
+.b8 116
+.b8 104
+.b8 105
+.b8 115
+
+.b8 0
+.b32 8829
+.b8 6
+.b8 144
+.b8 177
+.b8 200
+.b8 201
+.b8 171
+.b8 2
+.b8 2
+.b8 13
+
+.b32 8761
+.b8 5
+.b8 144
+.b8 177
+.b8 228
+.b8 149
+.b8 1
+.b8 2
+.b8 13
+
+.b32 8761
+.b8 5
+.b8 144
+.b8 178
+.b8 228
+.b8 149
+.b8 1
+.b8 2
+.b8 13
+
+.b32 8761
+.b8 5
+.b8 144
+.b8 179
+.b8 228
+.b8 149
+.b8 1
+.b8 2
+.b8 0
+.b8 2
+
+.b8 95
+.b8 90
+.b8 83
+.b8 116
+.b8 52
+.b8 102
+.b8 97
+.b8 98
+.b8 115
+.b8 102
+
+.b8 0
+.b8 95
+.b8 90
+.b8 83
+.b8 116
+.b8 52
+.b8 102
+.b8 97
+.b8 98
+.b8 115
+.b8 102
+
+.b8 0
+.b8 4
+.b8 241
+.b32 4872
+.b8 1
+.b64 func_begin9
+.b64 func_end9
+.b8 1
+.b8 156
+.b8 3
+
+.b8 95
+.b8 95
+.b8 120
+
+.b8 0
+.b8 4
+.b8 241
+.b32 4872
+.b8 5
+.b8 144
+.b8 177
+.b8 204
+.b8 149
+.b8 1
+.b8 2
+.b8 0
+.b8 14
+
+.b8 102
+.b8 108
+.b8 111
+.b8 97
+.b8 116
+
+.b8 0
+.b8 4
+.b8 4
+.b8 15
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+
+.b8 0
+.b8 4
+.b8 2
+.b16 1579
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 104
+.b8 114
+.b8 101
+.b8 97
+.b8 100
+.b8 115
+.b8 80
+.b8 101
+.b8 114
+.b8 66
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+
+.b8 0
+.b8 1
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 66
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+.b8 68
+.b8 105
+.b8 109
+.b8 88
+
+.b8 0
+.b8 2
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 66
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+.b8 68
+.b8 105
+.b8 109
+.b8 89
+
+.b8 0
+.b8 3
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 66
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+.b8 68
+.b8 105
+.b8 109
+.b8 90
+
+.b8 0
+.b8 4
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 71
+.b8 114
+.b8 105
+.b8 100
+.b8 68
+.b8 105
+.b8 109
+.b8 88
+
+.b8 0
+.b8 5
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 71
+.b8 114
+.b8 105
+.b8 100
+.b8 68
+.b8 105
+.b8 109
+.b8 89
+
+.b8 0
+.b8 6
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 71
+.b8 114
+.b8 105
+.b8 100
+.b8 68
+.b8 105
+.b8 109
+.b8 90
+
+.b8 0
+.b8 7
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 83
+.b8 104
+.b8 97
+.b8 114
+.b8 101
+.b8 100
+.b8 77
+.b8 101
+.b8 109
+.b8 111
+.b8 114
+.b8 121
+.b8 80
+.b8 101
+.b8 114
+.b8 66
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+
+.b8 0
+.b8 8
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 84
+.b8 111
+.b8 116
+.b8 97
+.b8 108
+.b8 67
+.b8 111
+.b8 110
+.b8 115
+.b8 116
+.b8 97
+.b8 110
+.b8 116
+.b8 77
+.b8 101
+.b8 109
+.b8 111
+.b8 114
+.b8 121
+
+.b8 0
+.b8 9
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 87
+.b8 97
+.b8 114
+.b8 112
+.b8 83
+.b8 105
+.b8 122
+.b8 101
+
+.b8 0
+.b8 10
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 80
+.b8 105
+.b8 116
+.b8 99
+.b8 104
+
+.b8 0
+.b8 11
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 82
+.b8 101
+.b8 103
+.b8 105
+.b8 115
+.b8 116
+.b8 101
+.b8 114
+.b8 115
+.b8 80
+.b8 101
+.b8 114
+.b8 66
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+
+.b8 0
+.b8 12
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 67
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+.b8 82
+.b8 97
+.b8 116
+.b8 101
+
+.b8 0
+.b8 13
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 65
+.b8 108
+.b8 105
+.b8 103
+.b8 110
+.b8 109
+.b8 101
+.b8 110
+.b8 116
+
+.b8 0
+.b8 14
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 71
+.b8 112
+.b8 117
+.b8 79
+.b8 118
+.b8 101
+.b8 114
+.b8 108
+.b8 97
+.b8 112
+
+.b8 0
+.b8 15
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 117
+.b8 108
+.b8 116
+.b8 105
+.b8 80
+.b8 114
+.b8 111
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+.b8 111
+.b8 114
+.b8 67
+.b8 111
+.b8 117
+.b8 110
+.b8 116
+
+.b8 0
+.b8 16
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 75
+.b8 101
+.b8 114
+.b8 110
+.b8 101
+.b8 108
+.b8 69
+.b8 120
+.b8 101
+.b8 99
+.b8 84
+.b8 105
+.b8 109
+.b8 101
+.b8 111
+.b8 117
+.b8 116
+
+.b8 0
+.b8 17
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 73
+.b8 110
+.b8 116
+.b8 101
+.b8 103
+.b8 114
+.b8 97
+.b8 116
+.b8 101
+.b8 100
+
+.b8 0
+.b8 18
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 67
+.b8 97
+.b8 110
+.b8 77
+.b8 97
+.b8 112
+.b8 72
+.b8 111
+.b8 115
+.b8 116
+.b8 77
+.b8 101
+.b8 109
+.b8 111
+.b8 114
+.b8 121
+
+.b8 0
+.b8 19
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 67
+.b8 111
+.b8 109
+.b8 112
+.b8 117
+.b8 116
+.b8 101
+.b8 77
+.b8 111
+.b8 100
+.b8 101
+
+.b8 0
+.b8 20
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 49
+.b8 68
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 21
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 50
+.b8 68
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 22
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 50
+.b8 68
+.b8 72
+.b8 101
+.b8 105
+.b8 103
+.b8 104
+.b8 116
+
+.b8 0
+.b8 23
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 51
+.b8 68
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 24
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 51
+.b8 68
+.b8 72
+.b8 101
+.b8 105
+.b8 103
+.b8 104
+.b8 116
+
+.b8 0
+.b8 25
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 51
+.b8 68
+.b8 68
+.b8 101
+.b8 112
+.b8 116
+.b8 104
+
+.b8 0
+.b8 26
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 50
+.b8 68
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 101
+.b8 100
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 27
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 50
+.b8 68
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 101
+.b8 100
+.b8 72
+.b8 101
+.b8 105
+.b8 103
+.b8 104
+.b8 116
+
+.b8 0
+.b8 28
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 50
+.b8 68
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 101
+.b8 100
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 115
+
+.b8 0
+.b8 29
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 83
+.b8 117
+.b8 114
+.b8 102
+.b8 97
+.b8 99
+.b8 101
+.b8 65
+.b8 108
+.b8 105
+.b8 103
+.b8 110
+.b8 109
+.b8 101
+.b8 110
+.b8 116
+
+.b8 0
+.b8 30
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 67
+.b8 111
+.b8 110
+.b8 99
+.b8 117
+.b8 114
+.b8 114
+.b8 101
+.b8 110
+.b8 116
+.b8 75
+.b8 101
+.b8 114
+.b8 110
+.b8 101
+.b8 108
+.b8 115
+
+.b8 0
+.b8 31
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 69
+.b8 99
+.b8 99
+.b8 69
+.b8 110
+.b8 97
+.b8 98
+.b8 108
+.b8 101
+.b8 100
+
+.b8 0
+.b8 32
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 80
+.b8 99
+.b8 105
+.b8 66
+.b8 117
+.b8 115
+.b8 73
+.b8 100
+
+.b8 0
+.b8 33
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 80
+.b8 99
+.b8 105
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+.b8 73
+.b8 100
+
+.b8 0
+.b8 34
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 84
+.b8 99
+.b8 99
+.b8 68
+.b8 114
+.b8 105
+.b8 118
+.b8 101
+.b8 114
+
+.b8 0
+.b8 35
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 101
+.b8 109
+.b8 111
+.b8 114
+.b8 121
+.b8 67
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+.b8 82
+.b8 97
+.b8 116
+.b8 101
+
+.b8 0
+.b8 36
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 71
+.b8 108
+.b8 111
+.b8 98
+.b8 97
+.b8 108
+.b8 77
+.b8 101
+.b8 109
+.b8 111
+.b8 114
+.b8 121
+.b8 66
+.b8 117
+.b8 115
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 37
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 76
+.b8 50
+.b8 67
+.b8 97
+.b8 99
+.b8 104
+.b8 101
+.b8 83
+.b8 105
+.b8 122
+.b8 101
+
+.b8 0
+.b8 38
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 104
+.b8 114
+.b8 101
+.b8 97
+.b8 100
+.b8 115
+.b8 80
+.b8 101
+.b8 114
+.b8 77
+.b8 117
+.b8 108
+.b8 116
+.b8 105
+.b8 80
+.b8 114
+.b8 111
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+.b8 111
+.b8 114
+
+.b8 0
+.b8 39
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 65
+.b8 115
+.b8 121
+.b8 110
+.b8 99
+.b8 69
+.b8 110
+.b8 103
+.b8 105
+.b8 110
+.b8 101
+.b8 67
+.b8 111
+.b8 117
+.b8 110
+.b8 116
+
+.b8 0
+.b8 40
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 85
+.b8 110
+.b8 105
+.b8 102
+.b8 105
+.b8 101
+.b8 100
+.b8 65
+.b8 100
+.b8 100
+.b8 114
+.b8 101
+.b8 115
+.b8 115
+.b8 105
+.b8 110
+.b8 103
+
+.b8 0
+.b8 41
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 49
+.b8 68
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 101
+.b8 100
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 42
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 49
+.b8 68
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 101
+.b8 100
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 115
+
+.b8 0
+.b8 43
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 50
+.b8 68
+.b8 71
+.b8 97
+.b8 116
+.b8 104
+.b8 101
+.b8 114
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 45
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 50
+.b8 68
+.b8 71
+.b8 97
+.b8 116
+.b8 104
+.b8 101
+.b8 114
+.b8 72
+.b8 101
+.b8 105
+.b8 103
+.b8 104
+.b8 116
+
+.b8 0
+.b8 46
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 51
+.b8 68
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+.b8 65
+.b8 108
+.b8 116
+
+.b8 0
+.b8 47
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 51
+.b8 68
+.b8 72
+.b8 101
+.b8 105
+.b8 103
+.b8 104
+.b8 116
+.b8 65
+.b8 108
+.b8 116
+
+.b8 0
+.b8 48
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 51
+.b8 68
+.b8 68
+.b8 101
+.b8 112
+.b8 116
+.b8 104
+.b8 65
+.b8 108
+.b8 116
+
+.b8 0
+.b8 49
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 80
+.b8 99
+.b8 105
+.b8 68
+.b8 111
+.b8 109
+.b8 97
+.b8 105
+.b8 110
+.b8 73
+.b8 100
+
+.b8 0
+.b8 50
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 80
+.b8 105
+.b8 116
+.b8 99
+.b8 104
+.b8 65
+.b8 108
+.b8 105
+.b8 103
+.b8 110
+.b8 109
+.b8 101
+.b8 110
+.b8 116
+
+.b8 0
+.b8 51
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 67
+.b8 117
+.b8 98
+.b8 101
+.b8 109
+.b8 97
+.b8 112
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 52
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 67
+.b8 117
+.b8 98
+.b8 101
+.b8 109
+.b8 97
+.b8 112
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 101
+.b8 100
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 53
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 67
+.b8 117
+.b8 98
+.b8 101
+.b8 109
+.b8 97
+.b8 112
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 101
+.b8 100
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 115
+
+.b8 0
+.b8 54
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 83
+.b8 117
+.b8 114
+.b8 102
+.b8 97
+.b8 99
+.b8 101
+.b8 49
+.b8 68
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 55
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 83
+.b8 117
+.b8 114
+.b8 102
+.b8 97
+.b8 99
+.b8 101
+.b8 50
+.b8 68
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 56
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 83
+.b8 117
+.b8 114
+.b8 102
+.b8 97
+.b8 99
+.b8 101
+.b8 50
+.b8 68
+.b8 72
+.b8 101
+.b8 105
+.b8 103
+.b8 104
+.b8 116
+
+.b8 0
+.b8 57
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 83
+.b8 117
+.b8 114
+.b8 102
+.b8 97
+.b8 99
+.b8 101
+.b8 51
+.b8 68
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 58
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 83
+.b8 117
+.b8 114
+.b8 102
+.b8 97
+.b8 99
+.b8 101
+.b8 51
+.b8 68
+.b8 72
+.b8 101
+.b8 105
+.b8 103
+.b8 104
+.b8 116
+
+.b8 0
+.b8 59
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 83
+.b8 117
+.b8 114
+.b8 102
+.b8 97
+.b8 99
+.b8 101
+.b8 51
+.b8 68
+.b8 68
+.b8 101
+.b8 112
+.b8 116
+.b8 104
+
+.b8 0
+.b8 60
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 83
+.b8 117
+.b8 114
+.b8 102
+.b8 97
+.b8 99
+.b8 101
+.b8 49
+.b8 68
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 101
+.b8 100
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 61
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 83
+.b8 117
+.b8 114
+.b8 102
+.b8 97
+.b8 99
+.b8 101
+.b8 49
+.b8 68
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 101
+.b8 100
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 115
+
+.b8 0
+.b8 62
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 83
+.b8 117
+.b8 114
+.b8 102
+.b8 97
+.b8 99
+.b8 101
+.b8 50
+.b8 68
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 101
+.b8 100
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 63
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 83
+.b8 117
+.b8 114
+.b8 102
+.b8 97
+.b8 99
+.b8 101
+.b8 50
+.b8 68
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 101
+.b8 100
+.b8 72
+.b8 101
+.b8 105
+.b8 103
+.b8 104
+.b8 116
+
+.b8 0
+.b8 192
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 83
+.b8 117
+.b8 114
+.b8 102
+.b8 97
+.b8 99
+.b8 101
+.b8 50
+.b8 68
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 101
+.b8 100
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 115
+
+.b8 0
+.b8 193
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 83
+.b8 117
+.b8 114
+.b8 102
+.b8 97
+.b8 99
+.b8 101
+.b8 67
+.b8 117
+.b8 98
+.b8 101
+.b8 109
+.b8 97
+.b8 112
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 194
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 83
+.b8 117
+.b8 114
+.b8 102
+.b8 97
+.b8 99
+.b8 101
+.b8 67
+.b8 117
+.b8 98
+.b8 101
+.b8 109
+.b8 97
+.b8 112
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 101
+.b8 100
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 195
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 83
+.b8 117
+.b8 114
+.b8 102
+.b8 97
+.b8 99
+.b8 101
+.b8 67
+.b8 117
+.b8 98
+.b8 101
+.b8 109
+.b8 97
+.b8 112
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 101
+.b8 100
+.b8 76
+.b8 97
+.b8 121
+.b8 101
+.b8 114
+.b8 115
+
+.b8 0
+.b8 196
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 49
+.b8 68
+.b8 76
+.b8 105
+.b8 110
+.b8 101
+.b8 97
+.b8 114
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 197
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 50
+.b8 68
+.b8 76
+.b8 105
+.b8 110
+.b8 101
+.b8 97
+.b8 114
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 198
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 50
+.b8 68
+.b8 76
+.b8 105
+.b8 110
+.b8 101
+.b8 97
+.b8 114
+.b8 72
+.b8 101
+.b8 105
+.b8 103
+.b8 104
+.b8 116
+
+.b8 0
+.b8 199
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 50
+.b8 68
+.b8 76
+.b8 105
+.b8 110
+.b8 101
+.b8 97
+.b8 114
+.b8 80
+.b8 105
+.b8 116
+.b8 99
+.b8 104
+
+.b8 0
+.b8 200
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 50
+.b8 68
+.b8 77
+.b8 105
+.b8 112
+.b8 109
+.b8 97
+.b8 112
+.b8 112
+.b8 101
+.b8 100
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 201
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 50
+.b8 68
+.b8 77
+.b8 105
+.b8 112
+.b8 109
+.b8 97
+.b8 112
+.b8 112
+.b8 101
+.b8 100
+.b8 72
+.b8 101
+.b8 105
+.b8 103
+.b8 104
+.b8 116
+
+.b8 0
+.b8 202
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 67
+.b8 111
+.b8 109
+.b8 112
+.b8 117
+.b8 116
+.b8 101
+.b8 67
+.b8 97
+.b8 112
+.b8 97
+.b8 98
+.b8 105
+.b8 108
+.b8 105
+.b8 116
+.b8 121
+.b8 77
+.b8 97
+.b8 106
+.b8 111
+.b8 114
+
+.b8 0
+.b8 203
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 67
+.b8 111
+.b8 109
+.b8 112
+.b8 117
+.b8 116
+.b8 101
+.b8 67
+.b8 97
+.b8 112
+.b8 97
+.b8 98
+.b8 105
+.b8 108
+.b8 105
+.b8 116
+.b8 121
+.b8 77
+.b8 105
+.b8 110
+.b8 111
+.b8 114
+
+.b8 0
+.b8 204
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 84
+.b8 101
+.b8 120
+.b8 116
+.b8 117
+.b8 114
+.b8 101
+.b8 49
+.b8 68
+.b8 77
+.b8 105
+.b8 112
+.b8 109
+.b8 97
+.b8 112
+.b8 112
+.b8 101
+.b8 100
+.b8 87
+.b8 105
+.b8 100
+.b8 116
+.b8 104
+
+.b8 0
+.b8 205
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 83
+.b8 116
+.b8 114
+.b8 101
+.b8 97
+.b8 109
+.b8 80
+.b8 114
+.b8 105
+.b8 111
+.b8 114
+.b8 105
+.b8 116
+.b8 105
+.b8 101
+.b8 115
+.b8 83
+.b8 117
+.b8 112
+.b8 112
+.b8 111
+.b8 114
+.b8 116
+.b8 101
+.b8 100
+
+.b8 0
+.b8 206
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 71
+.b8 108
+.b8 111
+.b8 98
+.b8 97
+.b8 108
+.b8 76
+.b8 49
+.b8 67
+.b8 97
+.b8 99
+.b8 104
+.b8 101
+.b8 83
+.b8 117
+.b8 112
+.b8 112
+.b8 111
+.b8 114
+.b8 116
+.b8 101
+.b8 100
+
+.b8 0
+.b8 207
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 76
+.b8 111
+.b8 99
+.b8 97
+.b8 108
+.b8 76
+.b8 49
+.b8 67
+.b8 97
+.b8 99
+.b8 104
+.b8 101
+.b8 83
+.b8 117
+.b8 112
+.b8 112
+.b8 111
+.b8 114
+.b8 116
+.b8 101
+.b8 100
+
+.b8 0
+.b8 208
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 83
+.b8 104
+.b8 97
+.b8 114
+.b8 101
+.b8 100
+.b8 77
+.b8 101
+.b8 109
+.b8 111
+.b8 114
+.b8 121
+.b8 80
+.b8 101
+.b8 114
+.b8 77
+.b8 117
+.b8 108
+.b8 116
+.b8 105
+.b8 112
+.b8 114
+.b8 111
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+.b8 111
+.b8 114
+
+.b8 0
+.b8 209
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 82
+.b8 101
+.b8 103
+.b8 105
+.b8 115
+.b8 116
+.b8 101
+.b8 114
+.b8 115
+.b8 80
+.b8 101
+.b8 114
+.b8 77
+.b8 117
+.b8 108
+.b8 116
+.b8 105
+.b8 112
+.b8 114
+.b8 111
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+.b8 111
+.b8 114
+
+.b8 0
+.b8 210
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 110
+.b8 97
+.b8 103
+.b8 101
+.b8 100
+.b8 77
+.b8 101
+.b8 109
+.b8 111
+.b8 114
+.b8 121
+
+.b8 0
+.b8 211
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 73
+.b8 115
+.b8 77
+.b8 117
+.b8 108
+.b8 116
+.b8 105
+.b8 71
+.b8 112
+.b8 117
+.b8 66
+.b8 111
+.b8 97
+.b8 114
+.b8 100
+
+.b8 0
+.b8 212
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 117
+.b8 108
+.b8 116
+.b8 105
+.b8 71
+.b8 112
+.b8 117
+.b8 66
+.b8 111
+.b8 97
+.b8 114
+.b8 100
+.b8 71
+.b8 114
+.b8 111
+.b8 117
+.b8 112
+.b8 73
+.b8 68
+
+.b8 0
+.b8 213
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 72
+.b8 111
+.b8 115
+.b8 116
+.b8 78
+.b8 97
+.b8 116
+.b8 105
+.b8 118
+.b8 101
+.b8 65
+.b8 116
+.b8 111
+.b8 109
+.b8 105
+.b8 99
+.b8 83
+.b8 117
+.b8 112
+.b8 112
+.b8 111
+.b8 114
+.b8 116
+.b8 101
+.b8 100
+
+.b8 0
+.b8 214
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 83
+.b8 105
+.b8 110
+.b8 103
+.b8 108
+.b8 101
+.b8 84
+.b8 111
+.b8 68
+.b8 111
+.b8 117
+.b8 98
+.b8 108
+.b8 101
+.b8 80
+.b8 114
+.b8 101
+.b8 99
+.b8 105
+.b8 115
+.b8 105
+.b8 111
+.b8 110
+.b8 80
+.b8 101
+.b8 114
+.b8 102
+.b8 82
+.b8 97
+.b8 116
+.b8 105
+.b8 111
+
+.b8 0
+.b8 215
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 80
+.b8 97
+.b8 103
+.b8 101
+.b8 97
+.b8 98
+.b8 108
+.b8 101
+.b8 77
+.b8 101
+.b8 109
+.b8 111
+.b8 114
+.b8 121
+.b8 65
+.b8 99
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+
+.b8 0
+.b8 216
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 67
+.b8 111
+.b8 110
+.b8 99
+.b8 117
+.b8 114
+.b8 114
+.b8 101
+.b8 110
+.b8 116
+.b8 77
+.b8 97
+.b8 110
+.b8 97
+.b8 103
+.b8 101
+.b8 100
+.b8 65
+.b8 99
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+
+.b8 0
+.b8 217
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 67
+.b8 111
+.b8 109
+.b8 112
+.b8 117
+.b8 116
+.b8 101
+.b8 80
+.b8 114
+.b8 101
+.b8 101
+.b8 109
+.b8 112
+.b8 116
+.b8 105
+.b8 111
+.b8 110
+.b8 83
+.b8 117
+.b8 112
+.b8 112
+.b8 111
+.b8 114
+.b8 116
+.b8 101
+.b8 100
+
+.b8 0
+.b8 218
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 67
+.b8 97
+.b8 110
+.b8 85
+.b8 115
+.b8 101
+.b8 72
+.b8 111
+.b8 115
+.b8 116
+.b8 80
+.b8 111
+.b8 105
+.b8 110
+.b8 116
+.b8 101
+.b8 114
+.b8 70
+.b8 111
+.b8 114
+.b8 82
+.b8 101
+.b8 103
+.b8 105
+.b8 115
+.b8 116
+.b8 101
+.b8 114
+.b8 101
+.b8 100
+.b8 77
+.b8 101
+.b8 109
+
+.b8 0
+.b8 219
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 82
+.b8 101
+.b8 115
+.b8 101
+.b8 114
+.b8 118
+.b8 101
+.b8 100
+.b8 57
+.b8 50
+
+.b8 0
+.b8 220
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 82
+.b8 101
+.b8 115
+.b8 101
+.b8 114
+.b8 118
+.b8 101
+.b8 100
+.b8 57
+.b8 51
+
+.b8 0
+.b8 221
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 82
+.b8 101
+.b8 115
+.b8 101
+.b8 114
+.b8 118
+.b8 101
+.b8 100
+.b8 57
+.b8 52
+
+.b8 0
+.b8 222
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 67
+.b8 111
+.b8 111
+.b8 112
+.b8 101
+.b8 114
+.b8 97
+.b8 116
+.b8 105
+.b8 118
+.b8 101
+.b8 76
+.b8 97
+.b8 117
+.b8 110
+.b8 99
+.b8 104
+
+.b8 0
+.b8 223
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 67
+.b8 111
+.b8 111
+.b8 112
+.b8 101
+.b8 114
+.b8 97
+.b8 116
+.b8 105
+.b8 118
+.b8 101
+.b8 77
+.b8 117
+.b8 108
+.b8 116
+.b8 105
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+.b8 76
+.b8 97
+.b8 117
+.b8 110
+.b8 99
+.b8 104
+
+.b8 0
+.b8 224
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 83
+.b8 104
+.b8 97
+.b8 114
+.b8 101
+.b8 100
+.b8 77
+.b8 101
+.b8 109
+.b8 111
+.b8 114
+.b8 121
+.b8 80
+.b8 101
+.b8 114
+.b8 66
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+.b8 79
+.b8 112
+.b8 116
+.b8 105
+.b8 110
+
+.b8 0
+.b8 225
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 67
+.b8 97
+.b8 110
+.b8 70
+.b8 108
+.b8 117
+.b8 115
+.b8 104
+.b8 82
+.b8 101
+.b8 109
+.b8 111
+.b8 116
+.b8 101
+.b8 87
+.b8 114
+.b8 105
+.b8 116
+.b8 101
+.b8 115
+
+.b8 0
+.b8 226
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 72
+.b8 111
+.b8 115
+.b8 116
+.b8 82
+.b8 101
+.b8 103
+.b8 105
+.b8 115
+.b8 116
+.b8 101
+.b8 114
+.b8 83
+.b8 117
+.b8 112
+.b8 112
+.b8 111
+.b8 114
+.b8 116
+.b8 101
+.b8 100
+
+.b8 0
+.b8 227
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 80
+.b8 97
+.b8 103
+.b8 101
+.b8 97
+.b8 98
+.b8 108
+.b8 101
+.b8 77
+.b8 101
+.b8 109
+.b8 111
+.b8 114
+.b8 121
+.b8 65
+.b8 99
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+.b8 85
+.b8 115
+.b8 101
+.b8 115
+.b8 72
+.b8 111
+.b8 115
+.b8 116
+.b8 80
+.b8 97
+.b8 103
+.b8 101
+.b8 84
+.b8 97
+.b8 98
+.b8 108
+.b8 101
+.b8 115
+
+.b8 0
+.b8 228
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 68
+.b8 105
+.b8 114
+.b8 101
+.b8 99
+.b8 116
+.b8 77
+.b8 97
+.b8 110
+.b8 97
+.b8 103
+.b8 101
+.b8 100
+.b8 77
+.b8 101
+.b8 109
+.b8 65
+.b8 99
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+.b8 70
+.b8 114
+.b8 111
+.b8 109
+.b8 72
+.b8 111
+.b8 115
+.b8 116
+
+.b8 0
+.b8 229
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 77
+.b8 97
+.b8 120
+.b8 66
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+.b8 115
+.b8 80
+.b8 101
+.b8 114
+.b8 77
+.b8 117
+.b8 108
+.b8 116
+.b8 105
+.b8 112
+.b8 114
+.b8 111
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+.b8 111
+.b8 114
+
+.b8 0
+.b8 234
+.b8 0
+
+.b8 6
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 82
+.b8 101
+.b8 115
+.b8 101
+.b8 114
+.b8 118
+.b8 101
+.b8 100
+.b8 83
+.b8 104
+.b8 97
+.b8 114
+.b8 101
+.b8 100
+.b8 77
+.b8 101
+.b8 109
+.b8 111
+.b8 114
+.b8 121
+.b8 80
+.b8 101
+.b8 114
+.b8 66
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+
+.b8 0
+.b8 239
+.b8 0
+
+.b8 0
+.b8 4
+
+.b32 8406
+.b8 115
+.b8 105
+.b8 122
+.b8 101
+.b8 95
+.b8 116
+
+.b8 0
+.b8 14
+
+.b8 117
+.b8 110
+.b8 115
+.b8 105
+.b8 103
+.b8 110
+.b8 101
+.b8 100
+.b8 32
+.b8 108
+.b8 111
+.b8 110
+.b8 103
+
+.b8 0
+.b8 7
+.b8 8
+.b8 16
+
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 70
+.b8 117
+.b8 110
+.b8 99
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 105
+.b8 98
+.b8 117
+.b8 116
+.b8 101
+.b8 115
+
+.b8 0
+.b8 56
+.b8 5
+.b16 1408
+.b8 17
+
+.b8 115
+.b8 104
+.b8 97
+.b8 114
+.b8 101
+.b8 100
+.b8 83
+.b8 105
+.b8 122
+.b8 101
+.b8 66
+.b8 121
+.b8 116
+.b8 101
+.b8 115
+
+.b8 0
+.b32 8394
+.b8 5
+.b16 1415
+.b8 0
+.b8 1
+.b8 17
+
+.b8 99
+.b8 111
+.b8 110
+.b8 115
+.b8 116
+.b8 83
+.b8 105
+.b8 122
+.b8 101
+.b8 66
+.b8 121
+.b8 116
+.b8 101
+.b8 115
+
+.b8 0
+.b32 8394
+.b8 5
+.b16 1421
+.b8 8
+.b8 1
+.b8 17
+
+.b8 108
+.b8 111
+.b8 99
+.b8 97
+.b8 108
+.b8 83
+.b8 105
+.b8 122
+.b8 101
+.b8 66
+.b8 121
+.b8 116
+.b8 101
+.b8 115
+
+.b8 0
+.b32 8394
+.b8 5
+.b16 1426
+.b8 16
+.b8 1
+.b8 17
+
+.b8 109
+.b8 97
+.b8 120
+.b8 84
+.b8 104
+.b8 114
+.b8 101
+.b8 97
+.b8 100
+.b8 115
+.b8 80
+.b8 101
+.b8 114
+.b8 66
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+
+.b8 0
+.b32 8707
+.b8 5
+.b16 1433
+.b8 24
+.b8 1
+.b8 17
+
+.b8 110
+.b8 117
+.b8 109
+.b8 82
+.b8 101
+.b8 103
+.b8 115
+
+.b8 0
+.b32 8707
+.b8 5
+.b16 1438
+.b8 28
+.b8 1
+.b8 17
+
+.b8 112
+.b8 116
+.b8 120
+.b8 86
+.b8 101
+.b8 114
+.b8 115
+.b8 105
+.b8 111
+.b8 110
+
+.b8 0
+.b32 8707
+.b8 5
+.b16 1445
+.b8 32
+.b8 1
+.b8 17
+
+.b8 98
+.b8 105
+.b8 110
+.b8 97
+.b8 114
+.b8 121
+.b8 86
+.b8 101
+.b8 114
+.b8 115
+.b8 105
+.b8 111
+.b8 110
+
+.b8 0
+.b32 8707
+.b8 5
+.b16 1452
+.b8 36
+.b8 1
+.b8 17
+
+.b8 99
+.b8 97
+.b8 99
+.b8 104
+.b8 101
+.b8 77
+.b8 111
+.b8 100
+.b8 101
+.b8 67
+.b8 65
+
+.b8 0
+.b32 8707
+.b8 5
+.b16 1458
+.b8 40
+.b8 1
+.b8 17
+
+.b8 109
+.b8 97
+.b8 120
+.b8 68
+.b8 121
+.b8 110
+.b8 97
+.b8 109
+.b8 105
+.b8 99
+.b8 83
+.b8 104
+.b8 97
+.b8 114
+.b8 101
+.b8 100
+.b8 83
+.b8 105
+.b8 122
+.b8 101
+.b8 66
+.b8 121
+.b8 116
+.b8 101
+.b8 115
+
+.b8 0
+.b32 8707
+.b8 5
+.b16 1465
+.b8 44
+.b8 1
+.b8 17
+
+.b8 112
+.b8 114
+.b8 101
+.b8 102
+.b8 101
+.b8 114
+.b8 114
+.b8 101
+.b8 100
+.b8 83
+.b8 104
+.b8 109
+.b8 101
+.b8 109
+.b8 67
+.b8 97
+.b8 114
+.b8 118
+.b8 101
+.b8 111
+.b8 117
+.b8 116
+
+.b8 0
+.b32 8707
+.b8 5
+.b16 1474
+.b8 48
+.b8 1
+.b8 0
+.b8 14
+
+.b8 105
+.b8 110
+.b8 116
+
+.b8 0
+.b8 5
+.b8 4
+.b8 16
+
+.b8 100
+.b8 105
+.b8 109
+.b8 51
+
+.b8 0
+.b8 12
+.b8 3
+.b16 416
+.b8 17
+
+.b8 120
+
+.b8 0
+.b32 8761
+.b8 3
+.b16 418
+.b8 0
+.b8 1
+.b8 17
+
+.b8 121
+
+.b8 0
+.b32 8761
+.b8 3
+.b16 418
+.b8 4
+.b8 1
+.b8 17
+
+.b8 122
+
+.b8 0
+.b32 8761
+.b8 3
+.b16 418
+.b8 8
+.b8 1
+.b8 0
+.b8 14
+
+.b8 117
+.b8 110
+.b8 115
+.b8 105
+.b8 103
+.b8 110
+.b8 101
+.b8 100
+.b8 32
+.b8 105
+.b8 110
+.b8 116
+
+.b8 0
+.b8 7
+.b8 4
+.b8 18
+
+.b32 8783
+.b8 12
+.b8 18
+
+.b32 4557
+.b8 12
+.b8 18
+
+.b32 8423
+.b8 12
+.b8 18
+
+.b32 8801
+.b8 12
+.b8 19
+
+.b32 4557
+.b8 18
+
+.b32 8707
+.b8 12
+.b8 18
+
+.b32 8818
+.b8 12
+.b8 19
+
+.b32 4872
+.b8 18
+
+.b32 4872
+.b8 12
+.b8 19
+
+.b32 8834
+.b8 18
+
+.b32 8714
+.b8 12
+.b8 0
+}
+.section .debug_abbrev {
+.b8 1
+
+.b8 17
+
+.b8 1
+
+.b8 37
+
+.b8 8
+
+.b8 19
+
+.b8 11
+
+.b8 3
+
+.b8 8
+
+.b8 17
+
+.b8 1
+
+.b8 16
+
+.b8 6
+
+.b8 27
+
+.b8 8
+
+.b8 0
+
+.b8 0
+
+.b8 2
+
+.b8 46
+
+.b8 1
+
+.b8 135
+.b8 64
+
+.b8 8
+
+.b8 3
+
+.b8 8
+
+.b8 58
+
+.b8 11
+
+.b8 59
+
+.b8 11
+
+.b8 73
+
+.b8 19
+
+.b8 63
+
+.b8 12
+
+.b8 17
+
+.b8 1
+
+.b8 18
+
+.b8 1
+
+.b8 64
+
+.b8 10
+
+.b8 0
+
+.b8 0
+
+.b8 3
+
+.b8 5
+
+.b8 0
+
+.b8 3
+
+.b8 8
+
+.b8 58
+
+.b8 11
+
+.b8 59
+
+.b8 11
+
+.b8 73
+
+.b8 19
+
+.b8 2
+
+.b8 10
+
+.b8 51
+
+.b8 11
+
+.b8 0
+
+.b8 0
+
+.b8 4
+
+.b8 22
+
+.b8 0
+
+.b8 73
+
+.b8 19
+
+.b8 3
+
+.b8 8
+
+.b8 0
+
+.b8 0
+
+.b8 5
+
+.b8 4
+
+.b8 1
+
+.b8 3
+
+.b8 8
+
+.b8 11
+
+.b8 11
+
+.b8 58
+
+.b8 11
+
+.b8 59
+
+.b8 11
+
+.b8 0
+
+.b8 0
+
+.b8 6
+
+.b8 40
+
+.b8 0
+
+.b8 3
+
+.b8 8
+
+.b8 28
+
+.b8 13
+
+.b8 0
+
+.b8 0
+
+.b8 7
+
+.b8 11
+
+.b8 1
+
+.b8 17
+
+.b8 1
+
+.b8 18
+
+.b8 1
+
+.b8 0
+
+.b8 0
+
+.b8 8
+
+.b8 52
+
+.b8 0
+
+.b8 3
+
+.b8 8
+
+.b8 58
+
+.b8 11
+
+.b8 59
+
+.b8 11
+
+.b8 73
+
+.b8 19
+
+.b8 2
+
+.b8 10
+
+.b8 51
+
+.b8 11
+
+.b8 0
+
+.b8 0
+
+.b8 9
+
+.b8 59
+
+.b8 0
+
+.b8 3
+
+.b8 8
+
+.b8 0
+
+.b8 0
+
+.b8 10
+
+.b8 46
+
+.b8 1
+
+.b8 135
+.b8 64
+
+.b8 8
+
+.b8 3
+
+.b8 8
+
+.b8 58
+
+.b8 11
+
+.b8 59
+
+.b8 5
+
+.b8 73
+
+.b8 19
+
+.b8 63
+
+.b8 12
+
+.b8 17
+
+.b8 1
+
+.b8 18
+
+.b8 1
+
+.b8 64
+
+.b8 10
+
+.b8 0
+
+.b8 0
+
+.b8 11
+
+.b8 5
+
+.b8 0
+
+.b8 3
+
+.b8 8
+
+.b8 73
+
+.b8 19
+
+.b8 2
+
+.b8 10
+
+.b8 51
+
+.b8 11
+
+.b8 0
+
+.b8 0
+
+.b8 12
+
+.b8 5
+
+.b8 0
+
+.b8 3
+
+.b8 8
+
+.b8 58
+
+.b8 11
+
+.b8 59
+
+.b8 5
+
+.b8 73
+
+.b8 19
+
+.b8 2
+
+.b8 10
+
+.b8 51
+
+.b8 11
+
+.b8 0
+
+.b8 0
+
+.b8 13
+
+.b8 5
+
+.b8 0
+
+.b8 73
+
+.b8 19
+
+.b8 2
+
+.b8 10
+
+.b8 51
+
+.b8 11
+
+.b8 0
+
+.b8 0
+
+.b8 14
+
+.b8 36
+
+.b8 0
+
+.b8 3
+
+.b8 8
+
+.b8 62
+
+.b8 11
+
+.b8 11
+
+.b8 11
+
+.b8 0
+
+.b8 0
+
+.b8 15
+
+.b8 4
+
+.b8 1
+
+.b8 3
+
+.b8 8
+
+.b8 11
+
+.b8 11
+
+.b8 58
+
+.b8 11
+
+.b8 59
+
+.b8 5
+
+.b8 0
+
+.b8 0
+
+.b8 16
+
+.b8 19
+
+.b8 1
+
+.b8 3
+
+.b8 8
+
+.b8 11
+
+.b8 11
+
+.b8 58
+
+.b8 11
+
+.b8 59
+
+.b8 5
+
+.b8 0
+
+.b8 0
+
+.b8 17
+
+.b8 13
+
+.b8 0
+
+.b8 3
+
+.b8 8
+
+.b8 73
+
+.b8 19
+
+.b8 58
+
+.b8 11
+
+.b8 59
+
+.b8 5
+
+.b8 56
+
+.b8 11
+
+.b8 50
+
+.b8 11
+
+.b8 0
+
+.b8 0
+
+.b8 18
+
+.b8 15
+
+.b8 0
+
+.b8 73
+
+.b8 19
+
+.b8 51
+
+.b8 11
+
+.b8 0
+
+.b8 0
+
+.b8 19
+
+.b8 38
+
+.b8 0
+
+.b8 73
+
+.b8 19
+
+.b8 0
+
+.b8 0
+
+.b8 0
+
+}
+.section .debug_ranges {
+}
+.section .debug_pubnames {
+.b32 288
+.b8 2
+.b8 0
+.b32 .debug_info
+.b32 8837
+.b32 3565
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 70
+.b8 117
+.b8 110
+.b8 99
+.b8 71
+.b8 101
+.b8 116
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 105
+.b8 98
+.b8 117
+.b8 116
+.b8 101
+.b8 115
+.b8 0
+
+.b32 3675
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+.b8 71
+.b8 101
+.b8 116
+.b8 65
+.b8 116
+.b8 116
+.b8 114
+.b8 105
+.b8 98
+.b8 117
+.b8 116
+.b8 101
+.b8 0
+
+.b32 4362
+.b8 95
+.b8 90
+.b8 57
+.b8 118
+.b8 101
+.b8 99
+.b8 116
+.b8 111
+.b8 114
+.b8 65
+.b8 100
+.b8 100
+.b8 80
+.b8 75
+.b8 102
+.b8 83
+.b8 48
+.b8 95
+.b8 80
+.b8 102
+.b8 105
+.b8 0
+
+.b32 3886
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 79
+.b8 99
+.b8 99
+.b8 117
+.b8 112
+.b8 97
+.b8 110
+.b8 99
+.b8 121
+.b8 77
+.b8 97
+.b8 120
+.b8 65
+.b8 99
+.b8 116
+.b8 105
+.b8 118
+.b8 101
+.b8 66
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+.b8 115
+.b8 80
+.b8 101
+.b8 114
+.b8 77
+.b8 117
+.b8 108
+.b8 116
+.b8 105
+.b8 112
+.b8 114
+.b8 111
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+.b8 111
+.b8 114
+.b8 0
+
+.b32 102
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 77
+.b8 97
+.b8 108
+.b8 108
+.b8 111
+.b8 99
+.b8 0
+
+.b32 4693
+.b8 95
+.b8 90
+.b8 78
+.b8 52
+.b8 100
+.b8 105
+.b8 109
+.b8 51
+.b8 67
+.b8 50
+.b8 69
+.b8 106
+.b8 106
+.b8 106
+.b8 0
+
+.b32 4805
+.b8 95
+.b8 90
+.b8 83
+.b8 116
+.b8 52
+.b8 102
+.b8 97
+.b8 98
+.b8 115
+.b8 102
+.b8 0
+
+.b32 3809
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 71
+.b8 101
+.b8 116
+.b8 68
+.b8 101
+.b8 118
+.b8 105
+.b8 99
+.b8 101
+.b8 0
+
+.b32 4105
+.b8 99
+.b8 117
+.b8 100
+.b8 97
+.b8 79
+.b8 99
+.b8 99
+.b8 117
+.b8 112
+.b8 97
+.b8 110
+.b8 99
+.b8 121
+.b8 77
+.b8 97
+.b8 120
+.b8 65
+.b8 99
+.b8 116
+.b8 105
+.b8 118
+.b8 101
+.b8 66
+.b8 108
+.b8 111
+.b8 99
+.b8 107
+.b8 115
+.b8 80
+.b8 101
+.b8 114
+.b8 77
+.b8 117
+.b8 108
+.b8 116
+.b8 105
+.b8 112
+.b8 114
+.b8 111
+.b8 99
+.b8 101
+.b8 115
+.b8 115
+.b8 111
+.b8 114
+.b8 87
+.b8 105
+.b8 116
+.b8 104
+.b8 70
+.b8 108
+.b8 97
+.b8 103
+.b8 115
+.b8 0
+
+.b32 4563
+.b8 95
+.b8 90
+.b8 78
+.b8 52
+.b8 100
+.b8 105
+.b8 109
+.b8 51
+.b8 67
+.b8 49
+.b8 69
+.b8 106
+.b8 106
+.b8 106
+.b8 0
+
+.b32 0
+}
diff --git a/ptx/src/test/mod.rs b/ptx/src/test/mod.rs
new file mode 100644
index 0000000..0785f3e
--- /dev/null
+++ b/ptx/src/test/mod.rs
@@ -0,0 +1,49 @@
+use super::ptx;
+use super::TranslateError;
+
+mod spirv_run;
+
+fn parse_and_assert(s: &str) {
+ let mut errors = Vec::new();
+ ptx::ModuleParser::new().parse(&mut errors, s).unwrap();
+ assert!(errors.len() == 0);
+}
+
+fn compile_and_assert(s: &str) -> Result<(), TranslateError> {
+ let mut errors = Vec::new();
+ let ast = ptx::ModuleParser::new().parse(&mut errors, s).unwrap();
+ crate::to_spirv_module(ast)?;
+ Ok(())
+}
+
+#[test]
+fn empty() {
+ parse_and_assert(".version 6.5 .target sm_30, debug");
+}
+
+#[test]
+fn operands_ptx() {
+ let vector_add = include_str!("operands.ptx");
+ parse_and_assert(vector_add);
+}
+
+#[test]
+#[allow(non_snake_case)]
+fn vectorAdd_kernel64_ptx() -> Result<(), TranslateError> {
+ let vector_add = include_str!("vectorAdd_kernel64.ptx");
+ compile_and_assert(vector_add)
+}
+
+#[test]
+#[allow(non_snake_case)]
+fn _Z9vectorAddPKfS0_Pfi_ptx() -> Result<(), TranslateError> {
+ let vector_add = include_str!("_Z9vectorAddPKfS0_Pfi.ptx");
+ compile_and_assert(vector_add)
+}
+
+#[test]
+#[allow(non_snake_case)]
+fn vectorAdd_11_ptx() -> Result<(), TranslateError> {
+ let vector_add = include_str!("vectorAdd_11.ptx");
+ compile_and_assert(vector_add)
+}
diff --git a/ptx/src/test/operands.ptx b/ptx/src/test/operands.ptx
new file mode 100644
index 0000000..67c59f5
--- /dev/null
+++ b/ptx/src/test/operands.ptx
@@ -0,0 +1,33 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry foobar(
+ .param .u32 foobar_param_0
+)
+{
+ .reg .u32 %reg<10>;
+ .reg .u64 %reg_64;
+ .reg .pred p;
+ .reg .pred q;
+
+ // reg
+ ld.param.u32 %reg0, [foobar_param_0];
+ // reg with offset
+ ld.param.u32 %reg1, [foobar_param_0+1];
+ ld.param.u32 %reg2, [foobar_param_0+-1];
+ // immediate - only in local
+ ld.local.u32 %reg3, [1];
+
+ // ids
+ add.u32 %reg0, %reg1, %reg2;
+ // immediate
+ add.u32 %reg0, 1, %reg2;
+ // reg with offset
+ add.u32 %reg0, %reg1+1, %reg2+-1;
+ // suprisingly, setp accepts all forms
+ setp.eq.and.u32 p, %reg1+1, %reg2+-1, 2;
+
+ // vector index - only supported by mov (maybe: ld, st, tex)
+ mov.u32 %reg0, %ntid.x;
+}
diff --git a/ptx/src/test/spirv_build/bar_sync.ptx b/ptx/src/test/spirv_build/bar_sync.ptx
new file mode 100644
index 0000000..54c6663
--- /dev/null
+++ b/ptx/src/test/spirv_build/bar_sync.ptx
@@ -0,0 +1,10 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry bar_sync()
+{
+ .reg .u32 temp_32;
+ bar.sync temp_32;
+ ret;
+}
diff --git a/ptx/src/test/spirv_build/global_extern_array.ptx b/ptx/src/test/spirv_build/global_extern_array.ptx
new file mode 100644
index 0000000..fe0f19f
--- /dev/null
+++ b/ptx/src/test/spirv_build/global_extern_array.ptx
@@ -0,0 +1,5 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.extern .global .b32 foobar [1]; \ No newline at end of file
diff --git a/ptx/src/test/spirv_build/param_func_array_0.ptx b/ptx/src/test/spirv_build/param_func_array_0.ptx
new file mode 100644
index 0000000..005af52
--- /dev/null
+++ b/ptx/src/test/spirv_build/param_func_array_0.ptx
@@ -0,0 +1,10 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .func foobar(
+ .param .b32 foobar[]
+)
+{
+ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_fail/const_ptr.ptx b/ptx/src/test/spirv_fail/const_ptr.ptx
new file mode 100644
index 0000000..0efd729
--- /dev/null
+++ b/ptx/src/test/spirv_fail/const_ptr.ptx
@@ -0,0 +1,5 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.const .b32 foobar []; \ No newline at end of file
diff --git a/ptx/src/test/spirv_fail/global_ptr.ptx b/ptx/src/test/spirv_fail/global_ptr.ptx
new file mode 100644
index 0000000..7ce4c83
--- /dev/null
+++ b/ptx/src/test/spirv_fail/global_ptr.ptx
@@ -0,0 +1,5 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.global .b32 foobar []; \ No newline at end of file
diff --git a/ptx/src/test/spirv_fail/local_ptr.txt b/ptx/src/test/spirv_fail/local_ptr.txt
new file mode 100644
index 0000000..9375011
--- /dev/null
+++ b/ptx/src/test/spirv_fail/local_ptr.txt
@@ -0,0 +1,12 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+
+.visible .entry func()
+{
+
+ .local .b32 foobar [1];
+
+ ret;
+}
diff --git a/ptx/src/test/spirv_fail/param_entry_array_0.ptx b/ptx/src/test/spirv_fail/param_entry_array_0.ptx
new file mode 100644
index 0000000..86dd5eb
--- /dev/null
+++ b/ptx/src/test/spirv_fail/param_entry_array_0.ptx
@@ -0,0 +1,10 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry foobar(
+ .param .b32 foobar[]
+)
+{
+ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_fail/param_vector.ptx b/ptx/src/test/spirv_fail/param_vector.ptx
new file mode 100644
index 0000000..28895e2
--- /dev/null
+++ b/ptx/src/test/spirv_fail/param_vector.ptx
@@ -0,0 +1,10 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .func foobar(
+ .param .b32 .v2 foobar
+)
+{
+ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_fail/shared_ptr.ptx b/ptx/src/test/spirv_fail/shared_ptr.ptx
new file mode 100644
index 0000000..b1b815a
--- /dev/null
+++ b/ptx/src/test/spirv_fail/shared_ptr.ptx
@@ -0,0 +1,5 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+extern .shared .b32 foobar []; \ No newline at end of file
diff --git a/ptx/src/test/spirv_fail/shared_ptr2.ptx b/ptx/src/test/spirv_fail/shared_ptr2.ptx
new file mode 100644
index 0000000..fb2472a
--- /dev/null
+++ b/ptx/src/test/spirv_fail/shared_ptr2.ptx
@@ -0,0 +1,13 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.extern .shared .b32 foobar1 [];
+
+.visible .func _Z4dupaPf(
+ .param .b64 _Z4dupaPf_param_0
+)
+{
+.shared .b32 foobar2 [];
+ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/add.ptx b/ptx/src/test/spirv_run/add.ptx
new file mode 100644
index 0000000..6762eae
--- /dev/null
+++ b/ptx/src/test/spirv_run/add.ptx
@@ -0,0 +1,22 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry add(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp;
+ .reg .u64 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u64 temp, [in_addr];
+ add.u64 temp2, temp, 1;
+ st.u64 [out_addr], temp2;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/add.spvtxt b/ptx/src/test/spirv_run/add.spvtxt
new file mode 100644
index 0000000..d9a5b9e
--- /dev/null
+++ b/ptx/src/test/spirv_run/add.spvtxt
@@ -0,0 +1,47 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %23 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "add"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %26 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %ulong_1 = OpConstant %ulong 1
+ %1 = OpFunction %void None %26
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %21 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %19 = OpConvertUToPtr %_ptr_Generic_ulong %13
+ %12 = OpLoad %ulong %19
+ OpStore %6 %12
+ %15 = OpLoad %ulong %6
+ %14 = OpIAdd %ulong %15 %ulong_1
+ OpStore %7 %14
+ %16 = OpLoad %ulong %5
+ %17 = OpLoad %ulong %7
+ %20 = OpConvertUToPtr %_ptr_Generic_ulong %16
+ OpStore %20 %17
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/and.ptx b/ptx/src/test/spirv_run/and.ptx
new file mode 100644
index 0000000..88292a7
--- /dev/null
+++ b/ptx/src/test/spirv_run/and.ptx
@@ -0,0 +1,23 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry and(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u32 temp1;
+ .reg .u32 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u32 temp1, [in_addr];
+ ld.u32 temp2, [in_addr+4];
+ and.b32 temp1, temp1, temp2;
+ st.u32 [out_addr], temp1;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/and.spvtxt b/ptx/src/test/spirv_run/and.spvtxt
new file mode 100644
index 0000000..57c36e6
--- /dev/null
+++ b/ptx/src/test/spirv_run/and.spvtxt
@@ -0,0 +1,58 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %31 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "and"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %34 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %ulong_4 = OpConstant %ulong 4
+ %1 = OpFunction %void None %34
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %29 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ %7 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %23 = OpConvertUToPtr %_ptr_Generic_uint %13
+ %12 = OpLoad %uint %23
+ OpStore %6 %12
+ %15 = OpLoad %ulong %4
+ %22 = OpIAdd %ulong %15 %ulong_4
+ %24 = OpConvertUToPtr %_ptr_Generic_uint %22
+ %14 = OpLoad %uint %24
+ OpStore %7 %14
+ %17 = OpLoad %uint %6
+ %18 = OpLoad %uint %7
+ %26 = OpCopyObject %uint %17
+ %27 = OpCopyObject %uint %18
+ %25 = OpBitwiseAnd %uint %26 %27
+ %16 = OpCopyObject %uint %25
+ OpStore %6 %16
+ %19 = OpLoad %ulong %5
+ %20 = OpLoad %uint %6
+ %28 = OpConvertUToPtr %_ptr_Generic_uint %19
+ OpStore %28 %20
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/assertfail.ptx b/ptx/src/test/spirv_run/assertfail.ptx
new file mode 100644
index 0000000..47ecb53
--- /dev/null
+++ b/ptx/src/test/spirv_run/assertfail.ptx
@@ -0,0 +1,79 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.extern .func __assertfail
+(
+ .param .b64 __assertfail_param_0,
+ .param .b64 __assertfail_param_1,
+ .param .b32 __assertfail_param_2,
+ .param .b64 __assertfail_param_3,
+ .param .b64 __assertfail_param_4
+);
+
+.extern .func __assertfail
+(
+ .param .b64 __assertfail_param_0,
+ .param .b64 __assertfail_param_1,
+ .param .b32 __assertfail_param_2,
+ .param .b64 __assertfail_param_3,
+ .param .b64 __assertfail_param_4
+);
+
+.visible .entry assertfail(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp;
+ .reg .u64 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+
+
+ {
+ .reg .b32 temp_param_reg;
+ mov.u32 temp_param_reg, 0;
+ // <end>}
+ .param .b64 param0;
+ st.param.b64 [param0+0], in_addr;
+ .param .b64 param1;
+ st.param.b64 [param1+0], in_addr;
+ .param .b32 param2;
+ st.param.b32 [param2+0], temp_param_reg;
+ .param .b64 param3;
+ st.param.b64 [param3+0], in_addr;
+ .param .b64 param4;
+ st.param.b64 [param4+0], in_addr;
+ call.uni
+ __assertfail,
+ (
+ param0,
+ param1,
+ param2,
+ param3,
+ param4
+ );
+
+ //{
+ }
+
+ ld.u64 temp, [in_addr];
+ add.u64 temp2, temp, 1;
+ st.u64 [out_addr], temp2;
+ ret;
+}
+
+
+.extern .func __assertfail
+(
+ .param .b64 __assertfail_param_0,
+ .param .b64 __assertfail_param_1,
+ .param .b32 __assertfail_param_2,
+ .param .b64 __assertfail_param_3,
+ .param .b64 __assertfail_param_4
+);
diff --git a/ptx/src/test/spirv_run/assertfail.spvtxt b/ptx/src/test/spirv_run/assertfail.spvtxt
new file mode 100644
index 0000000..33cdb7f
--- /dev/null
+++ b/ptx/src/test/spirv_run/assertfail.spvtxt
@@ -0,0 +1,105 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %67 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %12 "assertfail"
+ OpDecorate %1 LinkageAttributes "__zluda_ptx_impl____assertfail" Import
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %73 = OpTypeFunction %void %_ptr_Function_ulong %_ptr_Function_ulong %_ptr_Function_uint %_ptr_Function_ulong %_ptr_Function_ulong
+ %74 = OpTypeFunction %void %ulong %ulong
+ %uint_0 = OpConstant %uint 0
+ %ulong_0 = OpConstant %ulong 0
+ %uchar = OpTypeInt 8 0
+%_ptr_Function_uchar = OpTypePointer Function %uchar
+ %ulong_0_0 = OpConstant %ulong 0
+ %ulong_0_1 = OpConstant %ulong 0
+ %ulong_0_2 = OpConstant %ulong 0
+ %ulong_0_3 = OpConstant %ulong 0
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %ulong_1 = OpConstant %ulong 1
+ %1 = OpFunction %void None %73
+ %61 = OpFunctionParameter %_ptr_Function_ulong
+ %62 = OpFunctionParameter %_ptr_Function_ulong
+ %63 = OpFunctionParameter %_ptr_Function_uint
+ %64 = OpFunctionParameter %_ptr_Function_ulong
+ %65 = OpFunctionParameter %_ptr_Function_ulong
+ OpFunctionEnd
+ %12 = OpFunction %void None %74
+ %25 = OpFunctionParameter %ulong
+ %26 = OpFunctionParameter %ulong
+ %60 = OpLabel
+ %13 = OpVariable %_ptr_Function_ulong Function
+ %14 = OpVariable %_ptr_Function_ulong Function
+ %15 = OpVariable %_ptr_Function_ulong Function
+ %16 = OpVariable %_ptr_Function_ulong Function
+ %17 = OpVariable %_ptr_Function_ulong Function
+ %18 = OpVariable %_ptr_Function_ulong Function
+ %19 = OpVariable %_ptr_Function_uint Function
+ %20 = OpVariable %_ptr_Function_ulong Function
+ %21 = OpVariable %_ptr_Function_ulong Function
+ %22 = OpVariable %_ptr_Function_uint Function
+ %23 = OpVariable %_ptr_Function_ulong Function
+ %24 = OpVariable %_ptr_Function_ulong Function
+ OpStore %13 %25
+ OpStore %14 %26
+ %27 = OpLoad %ulong %13
+ OpStore %15 %27
+ %28 = OpLoad %ulong %14
+ OpStore %16 %28
+ %53 = OpCopyObject %uint %uint_0
+ %29 = OpCopyObject %uint %53
+ OpStore %19 %29
+ %30 = OpLoad %ulong %15
+ %77 = OpBitcast %_ptr_Function_uchar %20
+ %78 = OpInBoundsPtrAccessChain %_ptr_Function_uchar %77 %ulong_0
+ %43 = OpBitcast %_ptr_Function_ulong %78
+ %54 = OpCopyObject %ulong %30
+ OpStore %43 %54
+ %31 = OpLoad %ulong %15
+ %79 = OpBitcast %_ptr_Function_uchar %21
+ %80 = OpInBoundsPtrAccessChain %_ptr_Function_uchar %79 %ulong_0_0
+ %45 = OpBitcast %_ptr_Function_ulong %80
+ %55 = OpCopyObject %ulong %31
+ OpStore %45 %55
+ %32 = OpLoad %uint %19
+ %81 = OpBitcast %_ptr_Function_uchar %22
+ %82 = OpInBoundsPtrAccessChain %_ptr_Function_uchar %81 %ulong_0_1
+ %47 = OpBitcast %_ptr_Function_uint %82
+ OpStore %47 %32
+ %33 = OpLoad %ulong %15
+ %83 = OpBitcast %_ptr_Function_uchar %23
+ %84 = OpInBoundsPtrAccessChain %_ptr_Function_uchar %83 %ulong_0_2
+ %49 = OpBitcast %_ptr_Function_ulong %84
+ %56 = OpCopyObject %ulong %33
+ OpStore %49 %56
+ %34 = OpLoad %ulong %15
+ %85 = OpBitcast %_ptr_Function_uchar %24
+ %86 = OpInBoundsPtrAccessChain %_ptr_Function_uchar %85 %ulong_0_3
+ %51 = OpBitcast %_ptr_Function_ulong %86
+ %57 = OpCopyObject %ulong %34
+ OpStore %51 %57
+ %87 = OpFunctionCall %void %1 %20 %21 %22 %23 %24
+ %36 = OpLoad %ulong %15
+ %58 = OpConvertUToPtr %_ptr_Generic_ulong %36
+ %35 = OpLoad %ulong %58
+ OpStore %17 %35
+ %38 = OpLoad %ulong %17
+ %37 = OpIAdd %ulong %38 %ulong_1
+ OpStore %18 %37
+ %39 = OpLoad %ulong %16
+ %40 = OpLoad %ulong %18
+ %59 = OpConvertUToPtr %_ptr_Generic_ulong %39
+ OpStore %59 %40
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/atom_add.ptx b/ptx/src/test/spirv_run/atom_add.ptx
new file mode 100644
index 0000000..5d1f667
--- /dev/null
+++ b/ptx/src/test/spirv_run/atom_add.ptx
@@ -0,0 +1,28 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry atom_add(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .shared .align 4 .b8 shared_mem[1024];
+
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u32 temp1;
+ .reg .u32 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u32 temp1, [in_addr];
+ ld.u32 temp2, [in_addr+4];
+ st.shared.u32 [shared_mem], temp1;
+ atom.shared.add.u32 temp1, [shared_mem], temp2;
+ ld.shared.u32 temp2, [shared_mem];
+ st.u32 [out_addr], temp1;
+ st.u32 [out_addr+4], temp2;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/atom_add.spvtxt b/ptx/src/test/spirv_run/atom_add.spvtxt
new file mode 100644
index 0000000..6a977e0
--- /dev/null
+++ b/ptx/src/test/spirv_run/atom_add.spvtxt
@@ -0,0 +1,76 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %38 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "atom_add" %4
+ OpDecorate %4 Alignment 4
+ %void = OpTypeVoid
+ %uint = OpTypeInt 32 0
+ %uchar = OpTypeInt 8 0
+ %uint_1024 = OpConstant %uint 1024
+%_arr_uchar_uint_1024 = OpTypeArray %uchar %uint_1024
+%_ptr_Workgroup__arr_uchar_uint_1024 = OpTypePointer Workgroup %_arr_uchar_uint_1024
+ %4 = OpVariable %_ptr_Workgroup__arr_uchar_uint_1024 Workgroup
+ %ulong = OpTypeInt 64 0
+ %46 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %ulong_4 = OpConstant %ulong 4
+%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
+ %uint_1 = OpConstant %uint 1
+ %uint_0 = OpConstant %uint 0
+ %ulong_4_0 = OpConstant %ulong 4
+ %1 = OpFunction %void None %46
+ %9 = OpFunctionParameter %ulong
+ %10 = OpFunctionParameter %ulong
+ %36 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_uint Function
+ %8 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %9
+ OpStore %3 %10
+ %11 = OpLoad %ulong %2
+ OpStore %5 %11
+ %12 = OpLoad %ulong %3
+ OpStore %6 %12
+ %14 = OpLoad %ulong %5
+ %29 = OpConvertUToPtr %_ptr_Generic_uint %14
+ %13 = OpLoad %uint %29
+ OpStore %7 %13
+ %16 = OpLoad %ulong %5
+ %26 = OpIAdd %ulong %16 %ulong_4
+ %30 = OpConvertUToPtr %_ptr_Generic_uint %26
+ %15 = OpLoad %uint %30
+ OpStore %8 %15
+ %17 = OpLoad %uint %7
+ %31 = OpBitcast %_ptr_Workgroup_uint %4
+ OpStore %31 %17
+ %19 = OpLoad %uint %8
+ %32 = OpBitcast %_ptr_Workgroup_uint %4
+ %18 = OpAtomicIAdd %uint %32 %uint_1 %uint_0 %19
+ OpStore %7 %18
+ %33 = OpBitcast %_ptr_Workgroup_uint %4
+ %20 = OpLoad %uint %33
+ OpStore %8 %20
+ %21 = OpLoad %ulong %6
+ %22 = OpLoad %uint %7
+ %34 = OpConvertUToPtr %_ptr_Generic_uint %21
+ OpStore %34 %22
+ %23 = OpLoad %ulong %6
+ %24 = OpLoad %uint %8
+ %28 = OpIAdd %ulong %23 %ulong_4_0
+ %35 = OpConvertUToPtr %_ptr_Generic_uint %28
+ OpStore %35 %24
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/atom_cas.ptx b/ptx/src/test/spirv_run/atom_cas.ptx
new file mode 100644
index 0000000..440a1cb
--- /dev/null
+++ b/ptx/src/test/spirv_run/atom_cas.ptx
@@ -0,0 +1,24 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry atom_cas(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u32 temp1;
+ .reg .u32 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u32 temp1, [in_addr];
+ atom.cas.b32 temp1, [in_addr+4], temp1, 100;
+ ld.u32 temp2, [in_addr+4];
+ st.u32 [out_addr], temp1;
+ st.u32 [out_addr+4], temp2;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/atom_cas.spvtxt b/ptx/src/test/spirv_run/atom_cas.spvtxt
new file mode 100644
index 0000000..b28d3bc
--- /dev/null
+++ b/ptx/src/test/spirv_run/atom_cas.spvtxt
@@ -0,0 +1,69 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %39 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "atom_cas"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %42 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %ulong_4 = OpConstant %ulong 4
+ %uint_100 = OpConstant %uint 100
+ %uint_1 = OpConstant %uint 1
+ %uint_0 = OpConstant %uint 0
+ %ulong_4_0 = OpConstant %ulong 4
+ %ulong_4_1 = OpConstant %ulong 4
+ %1 = OpFunction %void None %42
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %37 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ %7 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %30 = OpConvertUToPtr %_ptr_Generic_uint %13
+ %12 = OpLoad %uint %30
+ OpStore %6 %12
+ %15 = OpLoad %ulong %4
+ %16 = OpLoad %uint %6
+ %24 = OpIAdd %ulong %15 %ulong_4
+ %32 = OpConvertUToPtr %_ptr_Generic_uint %24
+ %33 = OpCopyObject %uint %16
+ %31 = OpAtomicCompareExchange %uint %32 %uint_1 %uint_0 %uint_0 %uint_100 %33
+ %14 = OpCopyObject %uint %31
+ OpStore %6 %14
+ %18 = OpLoad %ulong %4
+ %27 = OpIAdd %ulong %18 %ulong_4_0
+ %34 = OpConvertUToPtr %_ptr_Generic_uint %27
+ %17 = OpLoad %uint %34
+ OpStore %7 %17
+ %19 = OpLoad %ulong %5
+ %20 = OpLoad %uint %6
+ %35 = OpConvertUToPtr %_ptr_Generic_uint %19
+ OpStore %35 %20
+ %21 = OpLoad %ulong %5
+ %22 = OpLoad %uint %7
+ %29 = OpIAdd %ulong %21 %ulong_4_1
+ %36 = OpConvertUToPtr %_ptr_Generic_uint %29
+ OpStore %36 %22
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/atom_inc.ptx b/ptx/src/test/spirv_run/atom_inc.ptx
new file mode 100644
index 0000000..ed3df08
--- /dev/null
+++ b/ptx/src/test/spirv_run/atom_inc.ptx
@@ -0,0 +1,26 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry atom_inc(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u32 temp1;
+ .reg .u32 temp2;
+ .reg .u32 temp3;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ atom.inc.u32 temp1, [in_addr], 101;
+ atom.global.inc.u32 temp2, [in_addr], 101;
+ ld.u32 temp3, [in_addr];
+ st.u32 [out_addr], temp1;
+ st.u32 [out_addr+4], temp2;
+ st.u32 [out_addr+8], temp3;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/atom_inc.spvtxt b/ptx/src/test/spirv_run/atom_inc.spvtxt
new file mode 100644
index 0000000..9469835
--- /dev/null
+++ b/ptx/src/test/spirv_run/atom_inc.spvtxt
@@ -0,0 +1,81 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %47 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "atom_inc"
+ OpDecorate %38 LinkageAttributes "__zluda_ptx_impl__atom_relaxed_gpu_generic_inc" Import
+ OpDecorate %42 LinkageAttributes "__zluda_ptx_impl__atom_relaxed_gpu_global_inc" Import
+ %void = OpTypeVoid
+ %uint = OpTypeInt 32 0
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %51 = OpTypeFunction %uint %_ptr_Generic_uint %uint
+%_ptr_CrossWorkgroup_uint = OpTypePointer CrossWorkgroup %uint
+ %53 = OpTypeFunction %uint %_ptr_CrossWorkgroup_uint %uint
+ %ulong = OpTypeInt 64 0
+ %55 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %uint_101 = OpConstant %uint 101
+ %uint_101_0 = OpConstant %uint 101
+ %ulong_4 = OpConstant %ulong 4
+ %ulong_8 = OpConstant %ulong 8
+ %38 = OpFunction %uint None %51
+ %40 = OpFunctionParameter %_ptr_Generic_uint
+ %41 = OpFunctionParameter %uint
+ OpFunctionEnd
+ %42 = OpFunction %uint None %53
+ %44 = OpFunctionParameter %_ptr_CrossWorkgroup_uint
+ %45 = OpFunctionParameter %uint
+ OpFunctionEnd
+ %1 = OpFunction %void None %55
+ %9 = OpFunctionParameter %ulong
+ %10 = OpFunctionParameter %ulong
+ %37 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ %7 = OpVariable %_ptr_Function_uint Function
+ %8 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %9
+ OpStore %3 %10
+ %11 = OpLoad %ulong %2
+ OpStore %4 %11
+ %12 = OpLoad %ulong %3
+ OpStore %5 %12
+ %14 = OpLoad %ulong %4
+ %31 = OpConvertUToPtr %_ptr_Generic_uint %14
+ %13 = OpFunctionCall %uint %38 %31 %uint_101
+ OpStore %6 %13
+ %16 = OpLoad %ulong %4
+ %32 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %16
+ %15 = OpFunctionCall %uint %42 %32 %uint_101_0
+ OpStore %7 %15
+ %18 = OpLoad %ulong %4
+ %33 = OpConvertUToPtr %_ptr_Generic_uint %18
+ %17 = OpLoad %uint %33
+ OpStore %8 %17
+ %19 = OpLoad %ulong %5
+ %20 = OpLoad %uint %6
+ %34 = OpConvertUToPtr %_ptr_Generic_uint %19
+ OpStore %34 %20
+ %21 = OpLoad %ulong %5
+ %22 = OpLoad %uint %7
+ %28 = OpIAdd %ulong %21 %ulong_4
+ %35 = OpConvertUToPtr %_ptr_Generic_uint %28
+ OpStore %35 %22
+ %23 = OpLoad %ulong %5
+ %24 = OpLoad %uint %8
+ %30 = OpIAdd %ulong %23 %ulong_8
+ %36 = OpConvertUToPtr %_ptr_Generic_uint %30
+ OpStore %36 %24
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/b64tof64.ptx b/ptx/src/test/spirv_run/b64tof64.ptx
new file mode 100644
index 0000000..de028c7
--- /dev/null
+++ b/ptx/src/test/spirv_run/b64tof64.ptx
@@ -0,0 +1,25 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry b64tof64(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .f64 in_addr_f;
+ .reg .b64 in_addr;
+ .reg .u64 out_addr;
+
+ .reg.u64 temp;
+
+ ld.param.f64 in_addr_f, [input];
+ ld.param.u64 out_addr, [output];
+
+ mov.b64 in_addr, in_addr_f;
+
+ ld.u64 temp, [in_addr];
+ st.u64 [out_addr], temp;
+
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/b64tof64.spvtxt b/ptx/src/test/spirv_run/b64tof64.spvtxt
new file mode 100644
index 0000000..e8cfcf4
--- /dev/null
+++ b/ptx/src/test/spirv_run/b64tof64.spvtxt
@@ -0,0 +1,50 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %24 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "b64tof64"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %27 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %double = OpTypeFloat 64
+%_ptr_Function_double = OpTypePointer Function %double
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %1 = OpFunction %void None %27
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %22 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_double Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %18 = OpBitcast %_ptr_Function_double %2
+ %10 = OpLoad %double %18
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %6 %11
+ %13 = OpLoad %double %4
+ %19 = OpBitcast %ulong %13
+ %12 = OpCopyObject %ulong %19
+ OpStore %5 %12
+ %15 = OpLoad %ulong %5
+ %20 = OpConvertUToPtr %_ptr_Generic_ulong %15
+ %14 = OpLoad %ulong %20
+ OpStore %7 %14
+ %16 = OpLoad %ulong %6
+ %17 = OpLoad %ulong %7
+ %21 = OpConvertUToPtr %_ptr_Generic_ulong %16
+ OpStore %21 %17
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/bfe.ptx b/ptx/src/test/spirv_run/bfe.ptx
new file mode 100644
index 0000000..60ee8a6
--- /dev/null
+++ b/ptx/src/test/spirv_run/bfe.ptx
@@ -0,0 +1,23 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry bfe(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u32 temp<3>;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u32 temp0, [in_addr];
+ ld.u32 temp1, [in_addr+4];
+ ld.u32 temp2, [in_addr+8];
+ bfe.u32 temp0, temp0, temp1, temp2;
+ st.u32 [out_addr], temp0;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/bfe.spvtxt b/ptx/src/test/spirv_run/bfe.spvtxt
new file mode 100644
index 0000000..5f9edad
--- /dev/null
+++ b/ptx/src/test/spirv_run/bfe.spvtxt
@@ -0,0 +1,70 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %40 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "bfe"
+ OpDecorate %34 LinkageAttributes "__zluda_ptx_impl__bfe_u32" Import
+ %void = OpTypeVoid
+ %uint = OpTypeInt 32 0
+ %43 = OpTypeFunction %uint %uint %uint %uint
+ %ulong = OpTypeInt 64 0
+ %45 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %ulong_4 = OpConstant %ulong 4
+ %ulong_8 = OpConstant %ulong 8
+ %34 = OpFunction %uint None %43
+ %36 = OpFunctionParameter %uint
+ %37 = OpFunctionParameter %uint
+ %38 = OpFunctionParameter %uint
+ OpFunctionEnd
+ %1 = OpFunction %void None %45
+ %9 = OpFunctionParameter %ulong
+ %10 = OpFunctionParameter %ulong
+ %33 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ %7 = OpVariable %_ptr_Function_uint Function
+ %8 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %9
+ OpStore %3 %10
+ %11 = OpLoad %ulong %2
+ OpStore %4 %11
+ %12 = OpLoad %ulong %3
+ OpStore %5 %12
+ %14 = OpLoad %ulong %4
+ %29 = OpConvertUToPtr %_ptr_Generic_uint %14
+ %13 = OpLoad %uint %29
+ OpStore %6 %13
+ %16 = OpLoad %ulong %4
+ %26 = OpIAdd %ulong %16 %ulong_4
+ %30 = OpConvertUToPtr %_ptr_Generic_uint %26
+ %15 = OpLoad %uint %30
+ OpStore %7 %15
+ %18 = OpLoad %ulong %4
+ %28 = OpIAdd %ulong %18 %ulong_8
+ %31 = OpConvertUToPtr %_ptr_Generic_uint %28
+ %17 = OpLoad %uint %31
+ OpStore %8 %17
+ %20 = OpLoad %uint %6
+ %21 = OpLoad %uint %7
+ %22 = OpLoad %uint %8
+ %19 = OpFunctionCall %uint %34 %20 %21 %22
+ OpStore %6 %19
+ %23 = OpLoad %ulong %5
+ %24 = OpLoad %uint %6
+ %32 = OpConvertUToPtr %_ptr_Generic_uint %23
+ OpStore %32 %24
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/block.ptx b/ptx/src/test/spirv_run/block.ptx
new file mode 100644
index 0000000..03c552c
--- /dev/null
+++ b/ptx/src/test/spirv_run/block.ptx
@@ -0,0 +1,26 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry block(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp;
+ .reg .u64 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u64 temp, [in_addr];
+ add.u64 temp2, temp, 1;
+ {
+ .reg .u64 temp2;
+ add.u64 temp2, temp2, 1;
+ }
+ st.u64 [out_addr], temp2;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/block.spvtxt b/ptx/src/test/spirv_run/block.spvtxt
new file mode 100644
index 0000000..fe7e63a
--- /dev/null
+++ b/ptx/src/test/spirv_run/block.spvtxt
@@ -0,0 +1,52 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %27 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "block"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %30 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %ulong_1 = OpConstant %ulong 1
+ %ulong_1_0 = OpConstant %ulong 1
+ %1 = OpFunction %void None %30
+ %9 = OpFunctionParameter %ulong
+ %10 = OpFunctionParameter %ulong
+ %25 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ %8 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %9
+ OpStore %3 %10
+ %11 = OpLoad %ulong %2
+ OpStore %4 %11
+ %12 = OpLoad %ulong %3
+ OpStore %5 %12
+ %14 = OpLoad %ulong %4
+ %23 = OpConvertUToPtr %_ptr_Generic_ulong %14
+ %13 = OpLoad %ulong %23
+ OpStore %6 %13
+ %16 = OpLoad %ulong %6
+ %15 = OpIAdd %ulong %16 %ulong_1
+ OpStore %7 %15
+ %18 = OpLoad %ulong %8
+ %17 = OpIAdd %ulong %18 %ulong_1_0
+ OpStore %8 %17
+ %19 = OpLoad %ulong %5
+ %20 = OpLoad %ulong %7
+ %24 = OpConvertUToPtr %_ptr_Generic_ulong %19
+ OpStore %24 %20
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/bra.ptx b/ptx/src/test/spirv_run/bra.ptx
new file mode 100644
index 0000000..fd5a0a3
--- /dev/null
+++ b/ptx/src/test/spirv_run/bra.ptx
@@ -0,0 +1,28 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry bra(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp;
+ .reg .u64 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u64 temp, [in_addr];
+ bra case1;
+case1:
+ add.u64 temp2, temp, 1;
+ bra case3;
+case2:
+ add.u64 temp2, temp, 2;
+case3:
+ st.u64 [out_addr], temp2;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/bra.spvtxt b/ptx/src/test/spirv_run/bra.spvtxt
new file mode 100644
index 0000000..b20e61a
--- /dev/null
+++ b/ptx/src/test/spirv_run/bra.spvtxt
@@ -0,0 +1,57 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %29 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "bra"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %32 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %ulong_1 = OpConstant %ulong 1
+ %ulong_2 = OpConstant %ulong 2
+ %1 = OpFunction %void None %32
+ %11 = OpFunctionParameter %ulong
+ %12 = OpFunctionParameter %ulong
+ %27 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ %8 = OpVariable %_ptr_Function_ulong Function
+ %9 = OpVariable %_ptr_Function_ulong Function
+ %10 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %11
+ OpStore %3 %12
+ %13 = OpLoad %ulong %2
+ OpStore %7 %13
+ %14 = OpLoad %ulong %3
+ OpStore %8 %14
+ %16 = OpLoad %ulong %7
+ %25 = OpConvertUToPtr %_ptr_Generic_ulong %16
+ %15 = OpLoad %ulong %25
+ OpStore %9 %15
+ OpBranch %4
+ %4 = OpLabel
+ %18 = OpLoad %ulong %9
+ %17 = OpIAdd %ulong %18 %ulong_1
+ OpStore %10 %17
+ OpBranch %6
+ %35 = OpLabel
+ %20 = OpLoad %ulong %9
+ %19 = OpIAdd %ulong %20 %ulong_2
+ OpStore %10 %19
+ OpBranch %6
+ %6 = OpLabel
+ %21 = OpLoad %ulong %8
+ %22 = OpLoad %ulong %10
+ %26 = OpConvertUToPtr %_ptr_Generic_ulong %21
+ OpStore %26 %22
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/brev.ptx b/ptx/src/test/spirv_run/brev.ptx
new file mode 100644
index 0000000..1d9dd75
--- /dev/null
+++ b/ptx/src/test/spirv_run/brev.ptx
@@ -0,0 +1,21 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry brev(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .b32 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.b32 temp, [in_addr];
+ brev.b32 temp, temp;
+ st.b32 [out_addr], temp;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/brev.spvtxt b/ptx/src/test/spirv_run/brev.spvtxt
new file mode 100644
index 0000000..df5df53
--- /dev/null
+++ b/ptx/src/test/spirv_run/brev.spvtxt
@@ -0,0 +1,47 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %21 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "brev"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %24 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %1 = OpFunction %void None %24
+ %7 = OpFunctionParameter %ulong
+ %8 = OpFunctionParameter %ulong
+ %19 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %7
+ OpStore %3 %8
+ %9 = OpLoad %ulong %2
+ OpStore %4 %9
+ %10 = OpLoad %ulong %3
+ OpStore %5 %10
+ %12 = OpLoad %ulong %4
+ %17 = OpConvertUToPtr %_ptr_Generic_uint %12
+ %11 = OpLoad %uint %17
+ OpStore %6 %11
+ %14 = OpLoad %uint %6
+ %13 = OpBitReverse %uint %14
+ OpStore %6 %13
+ %15 = OpLoad %ulong %5
+ %16 = OpLoad %uint %6
+ %18 = OpConvertUToPtr %_ptr_Generic_uint %15
+ OpStore %18 %16
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/call.ptx b/ptx/src/test/spirv_run/call.ptx
new file mode 100644
index 0000000..f2ac39c
--- /dev/null
+++ b/ptx/src/test/spirv_run/call.ptx
@@ -0,0 +1,38 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.func (.param.u64 output) incr (.param.u64 input);
+
+.visible .entry call(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.global.u64 temp, [in_addr];
+ .param.u64 incr_in;
+ .param.u64 incr_out;
+ st.param.b64 [incr_in], temp;
+ call (incr_out), incr, (incr_in);
+ ld.param.u64 temp, [incr_out];
+ st.global.u64 [out_addr], temp;
+ ret;
+}
+
+.func (.param .u64 output) incr(
+ .param .u64 input
+)
+{
+ .reg .u64 temp;
+ ld.param.u64 temp, [input];
+ add.u64 temp, temp, 1;
+ st.param.u64 [output], temp;
+ ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/call.spvtxt b/ptx/src/test/spirv_run/call.spvtxt
new file mode 100644
index 0000000..31f5307
--- /dev/null
+++ b/ptx/src/test/spirv_run/call.spvtxt
@@ -0,0 +1,67 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %37 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %4 "call"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %40 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong
+ %44 = OpTypeFunction %void %_ptr_Function_ulong %_ptr_Function_ulong
+ %ulong_1 = OpConstant %ulong 1
+ %4 = OpFunction %void None %40
+ %12 = OpFunctionParameter %ulong
+ %13 = OpFunctionParameter %ulong
+ %26 = OpLabel
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ %8 = OpVariable %_ptr_Function_ulong Function
+ %9 = OpVariable %_ptr_Function_ulong Function
+ %10 = OpVariable %_ptr_Function_ulong Function
+ %11 = OpVariable %_ptr_Function_ulong Function
+ OpStore %5 %12
+ OpStore %6 %13
+ %14 = OpLoad %ulong %5
+ OpStore %7 %14
+ %15 = OpLoad %ulong %6
+ OpStore %8 %15
+ %17 = OpLoad %ulong %7
+ %22 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %17
+ %16 = OpLoad %ulong %22
+ OpStore %9 %16
+ %18 = OpLoad %ulong %9
+ %23 = OpBitcast %_ptr_Function_ulong %10
+ %24 = OpCopyObject %ulong %18
+ OpStore %23 %24
+ %43 = OpFunctionCall %void %1 %11 %10
+ %19 = OpLoad %ulong %11
+ OpStore %9 %19
+ %20 = OpLoad %ulong %8
+ %21 = OpLoad %ulong %9
+ %25 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %20
+ OpStore %25 %21
+ OpReturn
+ OpFunctionEnd
+ %1 = OpFunction %void None %44
+ %27 = OpFunctionParameter %_ptr_Function_ulong
+ %28 = OpFunctionParameter %_ptr_Function_ulong
+ %35 = OpLabel
+ %29 = OpVariable %_ptr_Function_ulong Function
+ %30 = OpLoad %ulong %28
+ OpStore %29 %30
+ %32 = OpLoad %ulong %29
+ %31 = OpIAdd %ulong %32 %ulong_1
+ OpStore %29 %31
+ %33 = OpLoad %ulong %29
+ OpStore %27 %33
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/clz.ptx b/ptx/src/test/spirv_run/clz.ptx
new file mode 100644
index 0000000..b475b90
--- /dev/null
+++ b/ptx/src/test/spirv_run/clz.ptx
@@ -0,0 +1,21 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry clz(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .b32 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.b32 temp, [in_addr];
+ clz.b32 temp, temp;
+ st.b32 [out_addr], temp;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/clz.spvtxt b/ptx/src/test/spirv_run/clz.spvtxt
new file mode 100644
index 0000000..5d1ebc8
--- /dev/null
+++ b/ptx/src/test/spirv_run/clz.spvtxt
@@ -0,0 +1,47 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %21 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "clz"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %24 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %1 = OpFunction %void None %24
+ %7 = OpFunctionParameter %ulong
+ %8 = OpFunctionParameter %ulong
+ %19 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %7
+ OpStore %3 %8
+ %9 = OpLoad %ulong %2
+ OpStore %4 %9
+ %10 = OpLoad %ulong %3
+ OpStore %5 %10
+ %12 = OpLoad %ulong %4
+ %17 = OpConvertUToPtr %_ptr_Generic_uint %12
+ %11 = OpLoad %uint %17
+ OpStore %6 %11
+ %14 = OpLoad %uint %6
+ %13 = OpExtInst %uint %21 clz %14
+ OpStore %6 %13
+ %15 = OpLoad %ulong %5
+ %16 = OpLoad %uint %6
+ %18 = OpConvertUToPtr %_ptr_Generic_uint %15
+ OpStore %18 %16
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/constant_f32.ptx b/ptx/src/test/spirv_run/constant_f32.ptx
new file mode 100644
index 0000000..8894658
--- /dev/null
+++ b/ptx/src/test/spirv_run/constant_f32.ptx
@@ -0,0 +1,21 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry constant_f32(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .f32 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.f32 temp, [in_addr];
+ mul.f32 temp, temp, 0f3f000000; // 0.5
+ st.f32 [out_addr], temp;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/constant_f32.spvtxt b/ptx/src/test/spirv_run/constant_f32.spvtxt
new file mode 100644
index 0000000..46193a2
--- /dev/null
+++ b/ptx/src/test/spirv_run/constant_f32.spvtxt
@@ -0,0 +1,48 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %22 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "constant_f32"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %25 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+%_ptr_Generic_float = OpTypePointer Generic %float
+ %float_0_5 = OpConstant %float 0.5
+ %1 = OpFunction %void None %25
+ %7 = OpFunctionParameter %ulong
+ %8 = OpFunctionParameter %ulong
+ %20 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_float Function
+ OpStore %2 %7
+ OpStore %3 %8
+ %9 = OpLoad %ulong %2
+ OpStore %4 %9
+ %10 = OpLoad %ulong %3
+ OpStore %5 %10
+ %12 = OpLoad %ulong %4
+ %18 = OpConvertUToPtr %_ptr_Generic_float %12
+ %11 = OpLoad %float %18
+ OpStore %6 %11
+ %14 = OpLoad %float %6
+ %13 = OpFMul %float %14 %float_0_5
+ OpStore %6 %13
+ %15 = OpLoad %ulong %5
+ %16 = OpLoad %float %6
+ %19 = OpConvertUToPtr %_ptr_Generic_float %15
+ OpStore %19 %16
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/constant_negative.ptx b/ptx/src/test/spirv_run/constant_negative.ptx
new file mode 100644
index 0000000..c723c38
--- /dev/null
+++ b/ptx/src/test/spirv_run/constant_negative.ptx
@@ -0,0 +1,21 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry constant_negative(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .s32 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.s32 temp, [in_addr];
+ mul.lo.s32 temp, temp, -1;
+ st.s32 [out_addr], temp;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/constant_negative.spvtxt b/ptx/src/test/spirv_run/constant_negative.spvtxt
new file mode 100644
index 0000000..5532e6e
--- /dev/null
+++ b/ptx/src/test/spirv_run/constant_negative.spvtxt
@@ -0,0 +1,48 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %22 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "constant_negative"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %25 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+%uint_4294967295 = OpConstant %uint 4294967295
+ %1 = OpFunction %void None %25
+ %7 = OpFunctionParameter %ulong
+ %8 = OpFunctionParameter %ulong
+ %20 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %7
+ OpStore %3 %8
+ %9 = OpLoad %ulong %2
+ OpStore %4 %9
+ %10 = OpLoad %ulong %3
+ OpStore %5 %10
+ %12 = OpLoad %ulong %4
+ %18 = OpConvertUToPtr %_ptr_Generic_uint %12
+ %11 = OpLoad %uint %18
+ OpStore %6 %11
+ %14 = OpLoad %uint %6
+ %13 = OpIMul %uint %14 %uint_4294967295
+ OpStore %6 %13
+ %15 = OpLoad %ulong %5
+ %16 = OpLoad %uint %6
+ %19 = OpConvertUToPtr %_ptr_Generic_uint %15
+ OpStore %19 %16
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/cos.ptx b/ptx/src/test/spirv_run/cos.ptx
new file mode 100644
index 0000000..7983f20
--- /dev/null
+++ b/ptx/src/test/spirv_run/cos.ptx
@@ -0,0 +1,21 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry cos(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .f32 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.f32 temp, [in_addr];
+ cos.approx.f32 temp, temp;
+ st.f32 [out_addr], temp;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/cos.spvtxt b/ptx/src/test/spirv_run/cos.spvtxt
new file mode 100644
index 0000000..6820142
--- /dev/null
+++ b/ptx/src/test/spirv_run/cos.spvtxt
@@ -0,0 +1,47 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %21 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "cos"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %24 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+%_ptr_Generic_float = OpTypePointer Generic %float
+ %1 = OpFunction %void None %24
+ %7 = OpFunctionParameter %ulong
+ %8 = OpFunctionParameter %ulong
+ %19 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_float Function
+ OpStore %2 %7
+ OpStore %3 %8
+ %9 = OpLoad %ulong %2
+ OpStore %4 %9
+ %10 = OpLoad %ulong %3
+ OpStore %5 %10
+ %12 = OpLoad %ulong %4
+ %17 = OpConvertUToPtr %_ptr_Generic_float %12
+ %11 = OpLoad %float %17
+ OpStore %6 %11
+ %14 = OpLoad %float %6
+ %13 = OpExtInst %float %21 cos %14
+ OpStore %6 %13
+ %15 = OpLoad %ulong %5
+ %16 = OpLoad %float %6
+ %18 = OpConvertUToPtr %_ptr_Generic_float %15
+ OpStore %18 %16
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/cvt_rni.ptx b/ptx/src/test/spirv_run/cvt_rni.ptx
new file mode 100644
index 0000000..ecf20f8
--- /dev/null
+++ b/ptx/src/test/spirv_run/cvt_rni.ptx
@@ -0,0 +1,25 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry cvt_rni(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .f32 temp1;
+ .reg .f32 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.f32 temp1, [in_addr];
+ ld.f32 temp2, [in_addr+4];
+ cvt.rni.f32.f32 temp1, temp1;
+ cvt.rni.f32.f32 temp2, temp2;
+ st.f32 [out_addr], temp1;
+ st.f32 [out_addr+4], temp2;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/cvt_rni.spvtxt b/ptx/src/test/spirv_run/cvt_rni.spvtxt
new file mode 100644
index 0000000..cad84a2
--- /dev/null
+++ b/ptx/src/test/spirv_run/cvt_rni.spvtxt
@@ -0,0 +1,63 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %34 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "cvt_rni"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %37 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+%_ptr_Generic_float = OpTypePointer Generic %float
+ %ulong_4 = OpConstant %ulong 4
+ %ulong_4_0 = OpConstant %ulong 4
+ %1 = OpFunction %void None %37
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %32 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_float Function
+ %7 = OpVariable %_ptr_Function_float Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %28 = OpConvertUToPtr %_ptr_Generic_float %13
+ %12 = OpLoad %float %28
+ OpStore %6 %12
+ %15 = OpLoad %ulong %4
+ %25 = OpIAdd %ulong %15 %ulong_4
+ %29 = OpConvertUToPtr %_ptr_Generic_float %25
+ %14 = OpLoad %float %29
+ OpStore %7 %14
+ %17 = OpLoad %float %6
+ %16 = OpExtInst %float %34 rint %17
+ OpStore %6 %16
+ %19 = OpLoad %float %7
+ %18 = OpExtInst %float %34 rint %19
+ OpStore %7 %18
+ %20 = OpLoad %ulong %5
+ %21 = OpLoad %float %6
+ %30 = OpConvertUToPtr %_ptr_Generic_float %20
+ OpStore %30 %21
+ %22 = OpLoad %ulong %5
+ %23 = OpLoad %float %7
+ %27 = OpIAdd %ulong %22 %ulong_4_0
+ %31 = OpConvertUToPtr %_ptr_Generic_float %27
+ OpStore %31 %23
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/cvt_sat_s_u.ptx b/ptx/src/test/spirv_run/cvt_sat_s_u.ptx
new file mode 100644
index 0000000..ef0a10f
--- /dev/null
+++ b/ptx/src/test/spirv_run/cvt_sat_s_u.ptx
@@ -0,0 +1,24 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry cvt_sat_s_u(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .s32 temp;
+ .reg .u32 temp2;
+ .reg .s32 temp3;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.s32 temp, [in_addr];
+ cvt.sat.u32.s32 temp2, temp;
+ cvt.s32.u32 temp3, temp2;
+ st.s32 [out_addr], temp3;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/cvt_sat_s_u.spvtxt b/ptx/src/test/spirv_run/cvt_sat_s_u.spvtxt
new file mode 100644
index 0000000..be321eb
--- /dev/null
+++ b/ptx/src/test/spirv_run/cvt_sat_s_u.spvtxt
@@ -0,0 +1,52 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %25 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "cvt_sat_s_u"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %28 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %1 = OpFunction %void None %28
+ %9 = OpFunctionParameter %ulong
+ %10 = OpFunctionParameter %ulong
+ %23 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ %7 = OpVariable %_ptr_Function_uint Function
+ %8 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %9
+ OpStore %3 %10
+ %11 = OpLoad %ulong %2
+ OpStore %4 %11
+ %12 = OpLoad %ulong %3
+ OpStore %5 %12
+ %14 = OpLoad %ulong %4
+ %21 = OpConvertUToPtr %_ptr_Generic_uint %14
+ %13 = OpLoad %uint %21
+ OpStore %6 %13
+ %16 = OpLoad %uint %6
+ %15 = OpSatConvertSToU %uint %16
+ OpStore %7 %15
+ %18 = OpLoad %uint %7
+ %17 = OpBitcast %uint %18
+ OpStore %8 %17
+ %19 = OpLoad %ulong %5
+ %20 = OpLoad %uint %8
+ %22 = OpConvertUToPtr %_ptr_Generic_uint %19
+ OpStore %22 %20
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/cvta.ptx b/ptx/src/test/spirv_run/cvta.ptx
new file mode 100644
index 0000000..c24c959
--- /dev/null
+++ b/ptx/src/test/spirv_run/cvta.ptx
@@ -0,0 +1,23 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry cvta(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .f32 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ cvta.to.global.u64 in_addr, in_addr;
+ cvta.to.global.u64 out_addr, out_addr;
+
+ ld.global.f32 temp, [in_addr];
+ st.global.f32 [out_addr], temp;
+ ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/cvta.spvtxt b/ptx/src/test/spirv_run/cvta.spvtxt
new file mode 100644
index 0000000..143d0a5
--- /dev/null
+++ b/ptx/src/test/spirv_run/cvta.spvtxt
@@ -0,0 +1,65 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %37 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "cvta"
+ %void = OpTypeVoid
+ %uchar = OpTypeInt 8 0
+%_ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %uchar
+ %41 = OpTypeFunction %void %_ptr_CrossWorkgroup_uchar %_ptr_CrossWorkgroup_uchar
+%_ptr_Function__ptr_CrossWorkgroup_uchar = OpTypePointer Function %_ptr_CrossWorkgroup_uchar
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+ %ulong = OpTypeInt 64 0
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_CrossWorkgroup_float = OpTypePointer CrossWorkgroup %float
+ %1 = OpFunction %void None %41
+ %17 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar
+ %18 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar
+ %35 = OpLabel
+ %2 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %3 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %7 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %8 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %6 = OpVariable %_ptr_Function_float Function
+ OpStore %2 %17
+ OpStore %3 %18
+ %10 = OpBitcast %_ptr_Function_ulong %2
+ %9 = OpLoad %ulong %10
+ %19 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %9
+ OpStore %7 %19
+ %12 = OpBitcast %_ptr_Function_ulong %3
+ %11 = OpLoad %ulong %12
+ %20 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %11
+ OpStore %8 %20
+ %21 = OpLoad %_ptr_CrossWorkgroup_uchar %7
+ %14 = OpConvertPtrToU %ulong %21
+ %30 = OpCopyObject %ulong %14
+ %29 = OpCopyObject %ulong %30
+ %13 = OpCopyObject %ulong %29
+ %22 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %13
+ OpStore %7 %22
+ %23 = OpLoad %_ptr_CrossWorkgroup_uchar %8
+ %16 = OpConvertPtrToU %ulong %23
+ %32 = OpCopyObject %ulong %16
+ %31 = OpCopyObject %ulong %32
+ %15 = OpCopyObject %ulong %31
+ %24 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %15
+ OpStore %8 %24
+ %26 = OpLoad %_ptr_CrossWorkgroup_uchar %7
+ %33 = OpBitcast %_ptr_CrossWorkgroup_float %26
+ %25 = OpLoad %float %33
+ OpStore %6 %25
+ %27 = OpLoad %_ptr_CrossWorkgroup_uchar %8
+ %28 = OpLoad %float %6
+ %34 = OpBitcast %_ptr_CrossWorkgroup_float %27
+ OpStore %34 %28
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/div_approx.ptx b/ptx/src/test/spirv_run/div_approx.ptx
new file mode 100644
index 0000000..b25e320
--- /dev/null
+++ b/ptx/src/test/spirv_run/div_approx.ptx
@@ -0,0 +1,23 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry div_approx(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .f32 temp1;
+ .reg .f32 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.f32 temp1, [in_addr];
+ ld.f32 temp2, [in_addr+4];
+ div.approx.f32 temp1, temp1, temp2;
+ st.f32 [out_addr], temp1;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/div_approx.spvtxt b/ptx/src/test/spirv_run/div_approx.spvtxt
new file mode 100644
index 0000000..c62888c
--- /dev/null
+++ b/ptx/src/test/spirv_run/div_approx.spvtxt
@@ -0,0 +1,56 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %28 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "div_approx"
+ OpDecorate %16 FPFastMathMode AllowRecip
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %31 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+%_ptr_Generic_float = OpTypePointer Generic %float
+ %ulong_4 = OpConstant %ulong 4
+ %1 = OpFunction %void None %31
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %26 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_float Function
+ %7 = OpVariable %_ptr_Function_float Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %23 = OpConvertUToPtr %_ptr_Generic_float %13
+ %12 = OpLoad %float %23
+ OpStore %6 %12
+ %15 = OpLoad %ulong %4
+ %22 = OpIAdd %ulong %15 %ulong_4
+ %24 = OpConvertUToPtr %_ptr_Generic_float %22
+ %14 = OpLoad %float %24
+ OpStore %7 %14
+ %17 = OpLoad %float %6
+ %18 = OpLoad %float %7
+ %16 = OpFDiv %float %17 %18
+ OpStore %6 %16
+ %19 = OpLoad %ulong %5
+ %20 = OpLoad %float %6
+ %25 = OpConvertUToPtr %_ptr_Generic_float %19
+ OpStore %25 %20
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/ex2.ptx b/ptx/src/test/spirv_run/ex2.ptx
new file mode 100644
index 0000000..1edbcc6
--- /dev/null
+++ b/ptx/src/test/spirv_run/ex2.ptx
@@ -0,0 +1,21 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry ex2(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .f32 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.f32 temp, [in_addr];
+ ex2.approx.f32 temp, temp;
+ st.f32 [out_addr], temp;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/ex2.spvtxt b/ptx/src/test/spirv_run/ex2.spvtxt
new file mode 100644
index 0000000..e9be3e3
--- /dev/null
+++ b/ptx/src/test/spirv_run/ex2.spvtxt
@@ -0,0 +1,47 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %21 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "ex2"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %24 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+%_ptr_Generic_float = OpTypePointer Generic %float
+ %1 = OpFunction %void None %24
+ %7 = OpFunctionParameter %ulong
+ %8 = OpFunctionParameter %ulong
+ %19 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_float Function
+ OpStore %2 %7
+ OpStore %3 %8
+ %9 = OpLoad %ulong %2
+ OpStore %4 %9
+ %10 = OpLoad %ulong %3
+ OpStore %5 %10
+ %12 = OpLoad %ulong %4
+ %17 = OpConvertUToPtr %_ptr_Generic_float %12
+ %11 = OpLoad %float %17
+ OpStore %6 %11
+ %14 = OpLoad %float %6
+ %13 = OpExtInst %float %21 exp2 %14
+ OpStore %6 %13
+ %15 = OpLoad %ulong %5
+ %16 = OpLoad %float %6
+ %18 = OpConvertUToPtr %_ptr_Generic_float %15
+ OpStore %18 %16
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/extern_shared.ptx b/ptx/src/test/spirv_run/extern_shared.ptx
new file mode 100644
index 0000000..ac5c256
--- /dev/null
+++ b/ptx/src/test/spirv_run/extern_shared.ptx
@@ -0,0 +1,24 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.extern .shared .b32 shared_mem [];
+
+.visible .entry extern_shared(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.global.u64 temp, [in_addr];
+ st.shared.u64 [shared_mem], temp;
+ ld.shared.u64 temp, [shared_mem];
+ st.global.u64 [out_addr], temp;
+ ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/extern_shared.spvtxt b/ptx/src/test/spirv_run/extern_shared.spvtxt
new file mode 100644
index 0000000..fca8ee7
--- /dev/null
+++ b/ptx/src/test/spirv_run/extern_shared.spvtxt
@@ -0,0 +1,66 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %30 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %2 "extern_shared" %1
+ %void = OpTypeVoid
+ %uint = OpTypeInt 32 0
+%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
+%_ptr_Workgroup__ptr_Workgroup_uint = OpTypePointer Workgroup %_ptr_Workgroup_uint
+ %1 = OpVariable %_ptr_Workgroup__ptr_Workgroup_uint Workgroup
+ %ulong = OpTypeInt 64 0
+ %uchar = OpTypeInt 8 0
+%_ptr_Workgroup_uchar = OpTypePointer Workgroup %uchar
+ %38 = OpTypeFunction %void %ulong %ulong %_ptr_Workgroup_uchar
+%_ptr_Function__ptr_Workgroup_uchar = OpTypePointer Function %_ptr_Workgroup_uchar
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong
+%_ptr_Function__ptr_Workgroup_uint = OpTypePointer Function %_ptr_Workgroup_uint
+%_ptr_Workgroup_ulong = OpTypePointer Workgroup %ulong
+ %2 = OpFunction %void None %38
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %26 = OpFunctionParameter %_ptr_Workgroup_uchar
+ %39 = OpLabel
+ %27 = OpVariable %_ptr_Function__ptr_Workgroup_uchar Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ OpStore %27 %26
+ OpBranch %24
+ %24 = OpLabel
+ OpStore %3 %8
+ OpStore %4 %9
+ %10 = OpLoad %ulong %3
+ OpStore %5 %10
+ %11 = OpLoad %ulong %4
+ OpStore %6 %11
+ %13 = OpLoad %ulong %5
+ %20 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %13
+ %12 = OpLoad %ulong %20
+ OpStore %7 %12
+ %28 = OpBitcast %_ptr_Function__ptr_Workgroup_uint %27
+ %14 = OpLoad %_ptr_Workgroup_uint %28
+ %15 = OpLoad %ulong %7
+ %21 = OpBitcast %_ptr_Workgroup_ulong %14
+ OpStore %21 %15
+ %29 = OpBitcast %_ptr_Function__ptr_Workgroup_uint %27
+ %17 = OpLoad %_ptr_Workgroup_uint %29
+ %22 = OpBitcast %_ptr_Workgroup_ulong %17
+ %16 = OpLoad %ulong %22
+ OpStore %7 %16
+ %18 = OpLoad %ulong %6
+ %19 = OpLoad %ulong %7
+ %23 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %18
+ OpStore %23 %19
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/extern_shared_call.ptx b/ptx/src/test/spirv_run/extern_shared_call.ptx
new file mode 100644
index 0000000..76b2ae7
--- /dev/null
+++ b/ptx/src/test/spirv_run/extern_shared_call.ptx
@@ -0,0 +1,35 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.extern .shared .align 4 .b32 shared_mem[];
+
+.func incr_shared_2_global()
+{
+ .reg .u64 temp;
+ ld.shared.u64 temp, [shared_mem];
+ add.u64 temp, temp, 2;
+ st.shared.u64 [shared_mem], temp;
+ ret;
+}
+
+
+.visible .entry extern_shared_call(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.global.u64 temp, [in_addr];
+ st.shared.u64 [shared_mem], temp;
+ call incr_shared_2_global;
+ ld.shared.u64 temp, [shared_mem];
+ st.global.u64 [out_addr], temp;
+ ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/extern_shared_call.spvtxt b/ptx/src/test/spirv_run/extern_shared_call.spvtxt
new file mode 100644
index 0000000..39f8683
--- /dev/null
+++ b/ptx/src/test/spirv_run/extern_shared_call.spvtxt
@@ -0,0 +1,93 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %46 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %14 "extern_shared_call" %1
+ OpDecorate %1 Alignment 4
+ %void = OpTypeVoid
+ %uint = OpTypeInt 32 0
+%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
+%_ptr_Workgroup__ptr_Workgroup_uint = OpTypePointer Workgroup %_ptr_Workgroup_uint
+ %1 = OpVariable %_ptr_Workgroup__ptr_Workgroup_uint Workgroup
+ %uchar = OpTypeInt 8 0
+%_ptr_Workgroup_uchar = OpTypePointer Workgroup %uchar
+ %53 = OpTypeFunction %void %_ptr_Workgroup_uchar
+%_ptr_Function__ptr_Workgroup_uchar = OpTypePointer Function %_ptr_Workgroup_uchar
+ %ulong = OpTypeInt 64 0
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Function__ptr_Workgroup_uint = OpTypePointer Function %_ptr_Workgroup_uint
+%_ptr_Workgroup_ulong = OpTypePointer Workgroup %ulong
+ %ulong_2 = OpConstant %ulong 2
+ %60 = OpTypeFunction %void %ulong %ulong %_ptr_Workgroup_uchar
+%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong
+ %2 = OpFunction %void None %53
+ %38 = OpFunctionParameter %_ptr_Workgroup_uchar
+ %54 = OpLabel
+ %39 = OpVariable %_ptr_Function__ptr_Workgroup_uchar Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ OpStore %39 %38
+ OpBranch %13
+ %13 = OpLabel
+ %40 = OpBitcast %_ptr_Function__ptr_Workgroup_uint %39
+ %5 = OpLoad %_ptr_Workgroup_uint %40
+ %11 = OpBitcast %_ptr_Workgroup_ulong %5
+ %4 = OpLoad %ulong %11
+ OpStore %3 %4
+ %7 = OpLoad %ulong %3
+ %6 = OpIAdd %ulong %7 %ulong_2
+ OpStore %3 %6
+ %41 = OpBitcast %_ptr_Function__ptr_Workgroup_uint %39
+ %8 = OpLoad %_ptr_Workgroup_uint %41
+ %9 = OpLoad %ulong %3
+ %12 = OpBitcast %_ptr_Workgroup_ulong %8
+ OpStore %12 %9
+ OpReturn
+ OpFunctionEnd
+ %14 = OpFunction %void None %60
+ %20 = OpFunctionParameter %ulong
+ %21 = OpFunctionParameter %ulong
+ %42 = OpFunctionParameter %_ptr_Workgroup_uchar
+ %61 = OpLabel
+ %43 = OpVariable %_ptr_Function__ptr_Workgroup_uchar Function
+ %15 = OpVariable %_ptr_Function_ulong Function
+ %16 = OpVariable %_ptr_Function_ulong Function
+ %17 = OpVariable %_ptr_Function_ulong Function
+ %18 = OpVariable %_ptr_Function_ulong Function
+ %19 = OpVariable %_ptr_Function_ulong Function
+ OpStore %43 %42
+ OpBranch %36
+ %36 = OpLabel
+ OpStore %15 %20
+ OpStore %16 %21
+ %22 = OpLoad %ulong %15
+ OpStore %17 %22
+ %23 = OpLoad %ulong %16
+ OpStore %18 %23
+ %25 = OpLoad %ulong %17
+ %32 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %25
+ %24 = OpLoad %ulong %32
+ OpStore %19 %24
+ %44 = OpBitcast %_ptr_Function__ptr_Workgroup_uint %43
+ %26 = OpLoad %_ptr_Workgroup_uint %44
+ %27 = OpLoad %ulong %19
+ %33 = OpBitcast %_ptr_Workgroup_ulong %26
+ OpStore %33 %27
+ %63 = OpFunctionCall %void %2 %42
+ %45 = OpBitcast %_ptr_Function__ptr_Workgroup_uint %43
+ %29 = OpLoad %_ptr_Workgroup_uint %45
+ %34 = OpBitcast %_ptr_Workgroup_ulong %29
+ %28 = OpLoad %ulong %34
+ OpStore %19 %28
+ %30 = OpLoad %ulong %18
+ %31 = OpLoad %ulong %19
+ %35 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %30
+ OpStore %35 %31
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/fma.ptx b/ptx/src/test/spirv_run/fma.ptx
new file mode 100644
index 0000000..171d306
--- /dev/null
+++ b/ptx/src/test/spirv_run/fma.ptx
@@ -0,0 +1,25 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry fma(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .f32 temp1;
+ .reg .f32 temp2;
+ .reg .f32 temp3;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.f32 temp1, [in_addr];
+ ld.f32 temp2, [in_addr+4];
+ ld.f32 temp3, [in_addr+8];
+ fma.rn.f32 temp1, temp1, temp2, temp3;
+ st.f32 [out_addr], temp1;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/fma.spvtxt b/ptx/src/test/spirv_run/fma.spvtxt
new file mode 100644
index 0000000..9716198
--- /dev/null
+++ b/ptx/src/test/spirv_run/fma.spvtxt
@@ -0,0 +1,63 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %35 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "fma"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %38 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+%_ptr_Generic_float = OpTypePointer Generic %float
+ %ulong_4 = OpConstant %ulong 4
+ %ulong_8 = OpConstant %ulong 8
+ %1 = OpFunction %void None %38
+ %9 = OpFunctionParameter %ulong
+ %10 = OpFunctionParameter %ulong
+ %33 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_float Function
+ %7 = OpVariable %_ptr_Function_float Function
+ %8 = OpVariable %_ptr_Function_float Function
+ OpStore %2 %9
+ OpStore %3 %10
+ %11 = OpLoad %ulong %2
+ OpStore %4 %11
+ %12 = OpLoad %ulong %3
+ OpStore %5 %12
+ %14 = OpLoad %ulong %4
+ %29 = OpConvertUToPtr %_ptr_Generic_float %14
+ %13 = OpLoad %float %29
+ OpStore %6 %13
+ %16 = OpLoad %ulong %4
+ %26 = OpIAdd %ulong %16 %ulong_4
+ %30 = OpConvertUToPtr %_ptr_Generic_float %26
+ %15 = OpLoad %float %30
+ OpStore %7 %15
+ %18 = OpLoad %ulong %4
+ %28 = OpIAdd %ulong %18 %ulong_8
+ %31 = OpConvertUToPtr %_ptr_Generic_float %28
+ %17 = OpLoad %float %31
+ OpStore %8 %17
+ %20 = OpLoad %float %6
+ %21 = OpLoad %float %7
+ %22 = OpLoad %float %8
+ %19 = OpExtInst %float %35 mad %20 %21 %22
+ OpStore %6 %19
+ %23 = OpLoad %ulong %5
+ %24 = OpLoad %float %6
+ %32 = OpConvertUToPtr %_ptr_Generic_float %23
+ OpStore %32 %24
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/global_array.ptx b/ptx/src/test/spirv_run/global_array.ptx
new file mode 100644
index 0000000..7ac8bce
--- /dev/null
+++ b/ptx/src/test/spirv_run/global_array.ptx
@@ -0,0 +1,22 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.global .s32 foobar[4] = {1};
+
+.visible .entry global_array(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u32 temp;
+
+ mov.u64 in_addr, foobar;
+ ld.param.u64 out_addr, [output];
+
+ ld.global.u32 temp, [in_addr];
+ st.global.u32 [out_addr], temp;
+ ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/global_array.spvtxt b/ptx/src/test/spirv_run/global_array.spvtxt
new file mode 100644
index 0000000..25874ac
--- /dev/null
+++ b/ptx/src/test/spirv_run/global_array.spvtxt
@@ -0,0 +1,53 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %21 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %2 "global_array" %1
+ %void = OpTypeVoid
+ %uint = OpTypeInt 32 0
+ %uint_4 = OpConstant %uint 4
+%_arr_uint_uint_4 = OpTypeArray %uint %uint_4
+ %uint_1 = OpConstant %uint 1
+ %uint_0 = OpConstant %uint 0
+ %28 = OpConstantComposite %_arr_uint_uint_4 %uint_1 %uint_0 %uint_0 %uint_0
+ %uint_4_0 = OpConstant %uint 4
+%_ptr_CrossWorkgroup__arr_uint_uint_4 = OpTypePointer CrossWorkgroup %_arr_uint_uint_4
+ %1 = OpVariable %_ptr_CrossWorkgroup__arr_uint_uint_4 CrossWorkgroup %28
+ %ulong = OpTypeInt 64 0
+ %32 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_CrossWorkgroup_uint = OpTypePointer CrossWorkgroup %uint
+ %2 = OpFunction %void None %32
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %19 = OpLabel
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_uint Function
+ OpStore %3 %8
+ OpStore %4 %9
+ %16 = OpConvertPtrToU %ulong %1
+ %10 = OpCopyObject %ulong %16
+ OpStore %5 %10
+ %11 = OpLoad %ulong %4
+ OpStore %6 %11
+ %13 = OpLoad %ulong %5
+ %17 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %13
+ %12 = OpLoad %uint %17
+ OpStore %7 %12
+ %14 = OpLoad %ulong %6
+ %15 = OpLoad %uint %7
+ %18 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %14
+ OpStore %18 %15
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/implicit_param.ptx b/ptx/src/test/spirv_run/implicit_param.ptx
new file mode 100644
index 0000000..1d46bc1
--- /dev/null
+++ b/ptx/src/test/spirv_run/implicit_param.ptx
@@ -0,0 +1,24 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry implicit_param(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .f32 temp;
+ .param .b32 temp_param;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.global.f32 temp, [in_addr];
+ st.param.f32 [temp_param], temp;
+ ld.param.f32 temp, [temp_param];
+ st.global.f32 [out_addr], temp;
+
+ ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/implicit_param.spvtxt b/ptx/src/test/spirv_run/implicit_param.spvtxt
new file mode 100644
index 0000000..a78e53f
--- /dev/null
+++ b/ptx/src/test/spirv_run/implicit_param.spvtxt
@@ -0,0 +1,53 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %24 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "implicit_param"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %27 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_CrossWorkgroup_float = OpTypePointer CrossWorkgroup %float
+ %1 = OpFunction %void None %27
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %22 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_float Function
+ %7 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %18 = OpConvertUToPtr %_ptr_CrossWorkgroup_float %13
+ %12 = OpLoad %float %18
+ OpStore %6 %12
+ %14 = OpLoad %float %6
+ %19 = OpBitcast %_ptr_Function_float %7
+ OpStore %19 %14
+ %20 = OpBitcast %_ptr_Function_float %7
+ %15 = OpLoad %float %20
+ OpStore %6 %15
+ %16 = OpLoad %ulong %5
+ %17 = OpLoad %float %6
+ %21 = OpConvertUToPtr %_ptr_CrossWorkgroup_float %16
+ OpStore %21 %17
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/ld_st.ptx b/ptx/src/test/spirv_run/ld_st.ptx
new file mode 100644
index 0000000..469a219
--- /dev/null
+++ b/ptx/src/test/spirv_run/ld_st.ptx
@@ -0,0 +1,20 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry ld_st(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u64 temp, [in_addr];
+ st.u64 [out_addr], temp;
+ ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/ld_st.spvtxt b/ptx/src/test/spirv_run/ld_st.spvtxt
new file mode 100644
index 0000000..8e3f98d
--- /dev/null
+++ b/ptx/src/test/spirv_run/ld_st.spvtxt
@@ -0,0 +1,42 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %19 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "ld_st"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %22 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %1 = OpFunction %void None %22
+ %7 = OpFunctionParameter %ulong
+ %8 = OpFunctionParameter %ulong
+ %17 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %7
+ OpStore %3 %8
+ %9 = OpLoad %ulong %2
+ OpStore %4 %9
+ %10 = OpLoad %ulong %3
+ OpStore %5 %10
+ %12 = OpLoad %ulong %4
+ %15 = OpConvertUToPtr %_ptr_Generic_ulong %12
+ %11 = OpLoad %ulong %15
+ OpStore %6 %11
+ %13 = OpLoad %ulong %5
+ %14 = OpLoad %ulong %6
+ %16 = OpConvertUToPtr %_ptr_Generic_ulong %13
+ OpStore %16 %14
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/ld_st_implicit.ptx b/ptx/src/test/spirv_run/ld_st_implicit.ptx
new file mode 100644
index 0000000..8562286
--- /dev/null
+++ b/ptx/src/test/spirv_run/ld_st_implicit.ptx
@@ -0,0 +1,20 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry ld_st_implicit(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .b64 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.global.f32 temp, [in_addr];
+ st.global.f32 [out_addr], temp;
+ ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/ld_st_implicit.spvtxt b/ptx/src/test/spirv_run/ld_st_implicit.spvtxt
new file mode 100644
index 0000000..35f715b
--- /dev/null
+++ b/ptx/src/test/spirv_run/ld_st_implicit.spvtxt
@@ -0,0 +1,49 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %21 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "ld_st_implicit"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %24 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %float = OpTypeFloat 32
+%_ptr_CrossWorkgroup_float = OpTypePointer CrossWorkgroup %float
+ %uint = OpTypeInt 32 0
+ %1 = OpFunction %void None %24
+ %7 = OpFunctionParameter %ulong
+ %8 = OpFunctionParameter %ulong
+ %19 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %7
+ OpStore %3 %8
+ %9 = OpLoad %ulong %2
+ OpStore %4 %9
+ %10 = OpLoad %ulong %3
+ OpStore %5 %10
+ %12 = OpLoad %ulong %4
+ %16 = OpConvertUToPtr %_ptr_CrossWorkgroup_float %12
+ %15 = OpLoad %float %16
+ %29 = OpBitcast %uint %15
+ %11 = OpUConvert %ulong %29
+ OpStore %6 %11
+ %13 = OpLoad %ulong %5
+ %14 = OpLoad %ulong %6
+ %17 = OpConvertUToPtr %_ptr_CrossWorkgroup_float %13
+ %30 = OpBitcast %ulong %14
+ %31 = OpUConvert %uint %30
+ %18 = OpBitcast %float %31
+ OpStore %17 %18
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/ld_st_offset.ptx b/ptx/src/test/spirv_run/ld_st_offset.ptx
new file mode 100644
index 0000000..60cba13
--- /dev/null
+++ b/ptx/src/test/spirv_run/ld_st_offset.ptx
@@ -0,0 +1,23 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry ld_st_offset(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u32 temp1;
+ .reg .u32 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u32 temp1, [in_addr];
+ ld.u32 temp2, [in_addr+4];
+ st.u32 [out_addr], temp2;
+ st.u32 [out_addr+4], temp1;
+ ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/ld_st_offset.spvtxt b/ptx/src/test/spirv_run/ld_st_offset.spvtxt
new file mode 100644
index 0000000..963d88a
--- /dev/null
+++ b/ptx/src/test/spirv_run/ld_st_offset.spvtxt
@@ -0,0 +1,57 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %30 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "ld_st_offset"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %33 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %ulong_4 = OpConstant %ulong 4
+ %ulong_4_0 = OpConstant %ulong 4
+ %1 = OpFunction %void None %33
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %28 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ %7 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %24 = OpConvertUToPtr %_ptr_Generic_uint %13
+ %12 = OpLoad %uint %24
+ OpStore %6 %12
+ %15 = OpLoad %ulong %4
+ %21 = OpIAdd %ulong %15 %ulong_4
+ %25 = OpConvertUToPtr %_ptr_Generic_uint %21
+ %14 = OpLoad %uint %25
+ OpStore %7 %14
+ %16 = OpLoad %ulong %5
+ %17 = OpLoad %uint %7
+ %26 = OpConvertUToPtr %_ptr_Generic_uint %16
+ OpStore %26 %17
+ %18 = OpLoad %ulong %5
+ %19 = OpLoad %uint %6
+ %23 = OpIAdd %ulong %18 %ulong_4_0
+ %27 = OpConvertUToPtr %_ptr_Generic_uint %23
+ OpStore %27 %19
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/lg2.ptx b/ptx/src/test/spirv_run/lg2.ptx
new file mode 100644
index 0000000..c571955
--- /dev/null
+++ b/ptx/src/test/spirv_run/lg2.ptx
@@ -0,0 +1,21 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry lg2(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .f32 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.f32 temp, [in_addr];
+ lg2.approx.f32 temp, temp;
+ st.f32 [out_addr], temp;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/lg2.spvtxt b/ptx/src/test/spirv_run/lg2.spvtxt
new file mode 100644
index 0000000..d30fe8a
--- /dev/null
+++ b/ptx/src/test/spirv_run/lg2.spvtxt
@@ -0,0 +1,47 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %21 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "lg2"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %24 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+%_ptr_Generic_float = OpTypePointer Generic %float
+ %1 = OpFunction %void None %24
+ %7 = OpFunctionParameter %ulong
+ %8 = OpFunctionParameter %ulong
+ %19 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_float Function
+ OpStore %2 %7
+ OpStore %3 %8
+ %9 = OpLoad %ulong %2
+ OpStore %4 %9
+ %10 = OpLoad %ulong %3
+ OpStore %5 %10
+ %12 = OpLoad %ulong %4
+ %17 = OpConvertUToPtr %_ptr_Generic_float %12
+ %11 = OpLoad %float %17
+ OpStore %6 %11
+ %14 = OpLoad %float %6
+ %13 = OpExtInst %float %21 log2 %14
+ OpStore %6 %13
+ %15 = OpLoad %ulong %5
+ %16 = OpLoad %float %6
+ %18 = OpConvertUToPtr %_ptr_Generic_float %15
+ OpStore %18 %16
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/local_align.ptx b/ptx/src/test/spirv_run/local_align.ptx
new file mode 100644
index 0000000..6e10de3
--- /dev/null
+++ b/ptx/src/test/spirv_run/local_align.ptx
@@ -0,0 +1,21 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry local_align(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .local .align 8 .b8 __local_depot0[8];
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u64 temp, [in_addr];
+ st.u64 [out_addr], temp;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/local_align.spvtxt b/ptx/src/test/spirv_run/local_align.spvtxt
new file mode 100644
index 0000000..915ac6f
--- /dev/null
+++ b/ptx/src/test/spirv_run/local_align.spvtxt
@@ -0,0 +1,49 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %20 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "local_align"
+ OpDecorate %4 Alignment 8
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %23 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+ %uchar = OpTypeInt 8 0
+ %uint_8 = OpConstant %uint 8
+%_arr_uchar_uint_8 = OpTypeArray %uchar %uint_8
+%_ptr_Function__arr_uchar_uint_8 = OpTypePointer Function %_arr_uchar_uint_8
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %1 = OpFunction %void None %23
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %18 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function__arr_uchar_uint_8 Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %5 %10
+ %11 = OpLoad %ulong %3
+ OpStore %6 %11
+ %13 = OpLoad %ulong %5
+ %16 = OpConvertUToPtr %_ptr_Generic_ulong %13
+ %12 = OpLoad %ulong %16
+ OpStore %7 %12
+ %14 = OpLoad %ulong %6
+ %15 = OpLoad %ulong %7
+ %17 = OpConvertUToPtr %_ptr_Generic_ulong %14
+ OpStore %17 %15
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/mad_s32.ptx b/ptx/src/test/spirv_run/mad_s32.ptx
new file mode 100644
index 0000000..a864266
--- /dev/null
+++ b/ptx/src/test/spirv_run/mad_s32.ptx
@@ -0,0 +1,28 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry mad_s32(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .s32 dst;
+ .reg .s32 src1;
+ .reg .s32 src2;
+ .reg .s32 src3;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.s32 src1, [in_addr];
+ ld.s32 src2, [in_addr+4];
+ ld.s32 src3, [in_addr+8];
+ mad.lo.s32 dst, src1, src2, src3;
+ st.s32 [out_addr], dst;
+ st.s32 [out_addr+4], dst;
+ st.s32 [out_addr+8], dst;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/mad_s32.spvtxt b/ptx/src/test/spirv_run/mad_s32.spvtxt
new file mode 100644
index 0000000..9150089
--- /dev/null
+++ b/ptx/src/test/spirv_run/mad_s32.spvtxt
@@ -0,0 +1,77 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %46 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "mad_s32"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %49 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %ulong_4 = OpConstant %ulong 4
+ %ulong_8 = OpConstant %ulong 8
+ %ulong_4_0 = OpConstant %ulong 4
+ %ulong_8_0 = OpConstant %ulong 8
+ %1 = OpFunction %void None %49
+ %10 = OpFunctionParameter %ulong
+ %11 = OpFunctionParameter %ulong
+ %44 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ %7 = OpVariable %_ptr_Function_uint Function
+ %8 = OpVariable %_ptr_Function_uint Function
+ %9 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %10
+ OpStore %3 %11
+ %12 = OpLoad %ulong %2
+ OpStore %4 %12
+ %13 = OpLoad %ulong %3
+ OpStore %5 %13
+ %15 = OpLoad %ulong %4
+ %38 = OpConvertUToPtr %_ptr_Generic_uint %15
+ %14 = OpLoad %uint %38
+ OpStore %7 %14
+ %17 = OpLoad %ulong %4
+ %31 = OpIAdd %ulong %17 %ulong_4
+ %39 = OpConvertUToPtr %_ptr_Generic_uint %31
+ %16 = OpLoad %uint %39
+ OpStore %8 %16
+ %19 = OpLoad %ulong %4
+ %33 = OpIAdd %ulong %19 %ulong_8
+ %40 = OpConvertUToPtr %_ptr_Generic_uint %33
+ %18 = OpLoad %uint %40
+ OpStore %9 %18
+ %21 = OpLoad %uint %7
+ %22 = OpLoad %uint %8
+ %23 = OpLoad %uint %9
+ %54 = OpIMul %uint %21 %22
+ %20 = OpIAdd %uint %23 %54
+ OpStore %6 %20
+ %24 = OpLoad %ulong %5
+ %25 = OpLoad %uint %6
+ %41 = OpConvertUToPtr %_ptr_Generic_uint %24
+ OpStore %41 %25
+ %26 = OpLoad %ulong %5
+ %27 = OpLoad %uint %6
+ %35 = OpIAdd %ulong %26 %ulong_4_0
+ %42 = OpConvertUToPtr %_ptr_Generic_uint %35
+ OpStore %42 %27
+ %28 = OpLoad %ulong %5
+ %29 = OpLoad %uint %6
+ %37 = OpIAdd %ulong %28 %ulong_8_0
+ %43 = OpConvertUToPtr %_ptr_Generic_uint %37
+ OpStore %43 %29
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/max.ptx b/ptx/src/test/spirv_run/max.ptx
new file mode 100644
index 0000000..8c72fe2
--- /dev/null
+++ b/ptx/src/test/spirv_run/max.ptx
@@ -0,0 +1,23 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry max(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .s32 temp1;
+ .reg .s32 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.s32 temp1, [in_addr];
+ ld.s32 temp2, [in_addr+4];
+ max.s32 temp1, temp1, temp2;
+ st.s32 [out_addr], temp1;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/max.spvtxt b/ptx/src/test/spirv_run/max.spvtxt
new file mode 100644
index 0000000..05eb705
--- /dev/null
+++ b/ptx/src/test/spirv_run/max.spvtxt
@@ -0,0 +1,55 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %28 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "max"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %31 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %ulong_4 = OpConstant %ulong 4
+ %1 = OpFunction %void None %31
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %26 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ %7 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %23 = OpConvertUToPtr %_ptr_Generic_uint %13
+ %12 = OpLoad %uint %23
+ OpStore %6 %12
+ %15 = OpLoad %ulong %4
+ %22 = OpIAdd %ulong %15 %ulong_4
+ %24 = OpConvertUToPtr %_ptr_Generic_uint %22
+ %14 = OpLoad %uint %24
+ OpStore %7 %14
+ %17 = OpLoad %uint %6
+ %18 = OpLoad %uint %7
+ %16 = OpExtInst %uint %28 s_max %17 %18
+ OpStore %6 %16
+ %19 = OpLoad %ulong %5
+ %20 = OpLoad %uint %6
+ %25 = OpConvertUToPtr %_ptr_Generic_uint %19
+ OpStore %25 %20
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/min.ptx b/ptx/src/test/spirv_run/min.ptx
new file mode 100644
index 0000000..0311cdb
--- /dev/null
+++ b/ptx/src/test/spirv_run/min.ptx
@@ -0,0 +1,23 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry min(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .s32 temp1;
+ .reg .s32 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.s32 temp1, [in_addr];
+ ld.s32 temp2, [in_addr+4];
+ min.s32 temp1, temp1, temp2;
+ st.s32 [out_addr], temp1;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/min.spvtxt b/ptx/src/test/spirv_run/min.spvtxt
new file mode 100644
index 0000000..d0d2b9a
--- /dev/null
+++ b/ptx/src/test/spirv_run/min.spvtxt
@@ -0,0 +1,55 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %28 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "min"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %31 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %ulong_4 = OpConstant %ulong 4
+ %1 = OpFunction %void None %31
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %26 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ %7 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %23 = OpConvertUToPtr %_ptr_Generic_uint %13
+ %12 = OpLoad %uint %23
+ OpStore %6 %12
+ %15 = OpLoad %ulong %4
+ %22 = OpIAdd %ulong %15 %ulong_4
+ %24 = OpConvertUToPtr %_ptr_Generic_uint %22
+ %14 = OpLoad %uint %24
+ OpStore %7 %14
+ %17 = OpLoad %uint %6
+ %18 = OpLoad %uint %7
+ %16 = OpExtInst %uint %28 s_min %17 %18
+ OpStore %6 %16
+ %19 = OpLoad %ulong %5
+ %20 = OpLoad %uint %6
+ %25 = OpConvertUToPtr %_ptr_Generic_uint %19
+ OpStore %25 %20
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/mod.rs b/ptx/src/test/spirv_run/mod.rs
new file mode 100644
index 0000000..86f9c16
--- /dev/null
+++ b/ptx/src/test/spirv_run/mod.rs
@@ -0,0 +1,523 @@
+use crate::ptx;
+use crate::translate;
+use rspirv::{
+ binary::{Assemble, Disassemble},
+ dr::{Block, Function, Instruction, Loader, Operand},
+};
+use spirv_headers::Word;
+use spirv_tools_sys::{
+ spv_binary, spv_endianness_t, spv_parsed_instruction_t, spv_result_t, spv_target_env,
+};
+use std::error;
+use std::ffi::{c_void, CStr, CString};
+use std::fmt;
+use std::fmt::{Debug, Display, Formatter};
+use std::hash::Hash;
+use std::mem;
+use std::slice;
+use std::{borrow::Cow, collections::HashMap, env, fs, path::PathBuf, ptr, str};
+use std::{cmp, collections::hash_map::Entry};
+
+macro_rules! test_ptx {
+ ($fn_name:ident, $input:expr, $output:expr) => {
+ paste::item! {
+ #[test]
+ fn [<$fn_name _ptx>]() -> Result<(), Box<dyn std::error::Error>> {
+ let ptx = include_str!(concat!(stringify!($fn_name), ".ptx"));
+ let input = $input;
+ let mut output = $output;
+ test_ptx_assert(stringify!($fn_name), ptx, &input, &mut output)
+ }
+ }
+
+ paste::item! {
+ #[test]
+ fn [<$fn_name _spvtxt>]() -> Result<(), Box<dyn std::error::Error>> {
+ let ptx_txt = include_str!(concat!(stringify!($fn_name), ".ptx"));
+ let spirv_file_name = concat!(stringify!($fn_name), ".spvtxt");
+ let spirv_txt = include_bytes!(concat!(stringify!($fn_name), ".spvtxt"));
+ test_spvtxt_assert(ptx_txt, spirv_txt, spirv_file_name)
+ }
+ }
+ };
+}
+
+test_ptx!(ld_st, [1u64], [1u64]);
+test_ptx!(ld_st_implicit, [0.5f32], [0.5f32]);
+test_ptx!(mov, [1u64], [1u64]);
+test_ptx!(mul_lo, [1u64], [2u64]);
+test_ptx!(mul_hi, [u64::max_value()], [1u64]);
+test_ptx!(add, [1u64], [2u64]);
+test_ptx!(setp, [10u64, 11u64], [1u64, 0u64]);
+test_ptx!(bra, [10u64], [11u64]);
+test_ptx!(not, [0u64], [u64::max_value()]);
+test_ptx!(shl, [11u64], [44u64]);
+test_ptx!(shl_link_hack, [11u64], [44u64]);
+test_ptx!(cvt_sat_s_u, [-1i32], [0i32]);
+test_ptx!(cvta, [3.0f32], [3.0f32]);
+test_ptx!(block, [1u64], [2u64]);
+test_ptx!(local_align, [1u64], [1u64]);
+test_ptx!(call, [1u64], [2u64]);
+test_ptx!(vector, [1u32, 2u32], [3u32, 3u32]);
+test_ptx!(ld_st_offset, [1u32, 2u32], [2u32, 1u32]);
+test_ptx!(ntid, [3u32], [4u32]);
+test_ptx!(reg_local, [12u64], [13u64]);
+test_ptx!(mov_address, [0xDEADu64], [0u64]);
+test_ptx!(b64tof64, [111u64], [111u64]);
+test_ptx!(implicit_param, [34u32], [34u32]);
+test_ptx!(pred_not, [10u64, 11u64], [2u64, 0u64]);
+test_ptx!(mad_s32, [2i32, 3i32, 4i32], [10i32, 10i32, 10i32]);
+test_ptx!(
+ mul_wide,
+ [0x01_00_00_00__01_00_00_00i64],
+ [0x1_00_00_00_00_00_00i64]
+);
+test_ptx!(vector_extract, [1u8, 2u8, 3u8, 4u8], [3u8, 4u8, 1u8, 2u8]);
+test_ptx!(shr, [-2i32], [-1i32]);
+test_ptx!(or, [1u64, 2u64], [3u64]);
+test_ptx!(sub, [2u64], [1u64]);
+test_ptx!(min, [555i32, 444i32], [444i32]);
+test_ptx!(max, [555i32, 444i32], [555i32]);
+test_ptx!(global_array, [0xDEADu32], [1u32]);
+test_ptx!(extern_shared, [127u64], [127u64]);
+test_ptx!(extern_shared_call, [121u64], [123u64]);
+test_ptx!(rcp, [2f32], [0.5f32]);
+// 0b1_00000000_10000000000000000000000u32 is a large denormal
+// 0x3f000000 is 0.5
+test_ptx!(
+ mul_ftz,
+ [0b1_00000000_10000000000000000000000u32, 0x3f000000u32],
+ [0b1_00000000_00000000000000000000000u32]
+);
+test_ptx!(
+ mul_non_ftz,
+ [0b1_00000000_10000000000000000000000u32, 0x3f000000u32],
+ [0b1_00000000_01000000000000000000000u32]
+);
+test_ptx!(constant_f32, [10f32], [5f32]);
+test_ptx!(constant_negative, [-101i32], [101i32]);
+test_ptx!(and, [6u32, 3u32], [2u32]);
+test_ptx!(selp, [100u16, 200u16], [200u16]);
+test_ptx!(selp_true, [100u16, 200u16], [100u16]);
+test_ptx!(fma, [2f32, 3f32, 5f32], [11f32]);
+test_ptx!(shared_variable, [513u64], [513u64]);
+test_ptx!(shared_ptr_32, [513u64], [513u64]);
+test_ptx!(atom_cas, [91u32, 91u32], [91u32, 100u32]);
+test_ptx!(atom_inc, [100u32], [100u32, 101u32, 0u32]);
+test_ptx!(atom_add, [2u32, 4u32], [2u32, 6u32]);
+test_ptx!(div_approx, [1f32, 2f32], [0.5f32]);
+test_ptx!(sqrt, [0.25f32], [0.5f32]);
+test_ptx!(rsqrt, [0.25f64], [2f64]);
+test_ptx!(neg, [181i32], [-181i32]);
+test_ptx!(sin, [std::f32::consts::PI / 2f32], [1f32]);
+test_ptx!(cos, [std::f32::consts::PI], [-1f32]);
+test_ptx!(lg2, [512f32], [9f32]);
+test_ptx!(ex2, [10f32], [1024f32]);
+test_ptx!(cvt_rni, [9.5f32, 10.5f32], [10f32, 10f32]);
+test_ptx!(clz, [0b00000101_00101101_00010011_10101011u32], [5u32]);
+test_ptx!(popc, [0b10111100_10010010_01001001_10001010u32], [14u32]);
+test_ptx!(
+ brev,
+ [0b11000111_01011100_10101110_11111011u32],
+ [0b11011111_01110101_00111010_11100011u32]
+);
+test_ptx!(
+ xor,
+ [
+ 0b01010010_00011010_01000000_00001101u32,
+ 0b11100110_10011011_00001100_00100011u32
+ ],
+ [0b10110100100000010100110000101110u32]
+);
+test_ptx!(rem, [21692i32, 13i32], [8i32]);
+test_ptx!(
+ bfe,
+ [0b11111000_11000001_00100010_10100000u32, 16u32, 8u32],
+ [0b11000001u32]
+);
+test_ptx!(stateful_ld_st_simple, [121u64], [121u64]);
+test_ptx!(stateful_ld_st_ntid, [123u64], [123u64]);
+test_ptx!(stateful_ld_st_ntid_chain, [12651u64], [12651u64]);
+test_ptx!(stateful_ld_st_ntid_sub, [96311u64], [96311u64]);
+test_ptx!(shared_ptr_take_address, [97815231u64], [97815231u64]);
+// For now, we just that it builds and links
+test_ptx!(assertfail, [716523871u64], [716523872u64]);
+
+struct DisplayError<T: Debug> {
+ err: T,
+}
+
+impl<T: Debug> Display for DisplayError<T> {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ Debug::fmt(&self.err, f)
+ }
+}
+
+impl<T: Debug> Debug for DisplayError<T> {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ Debug::fmt(&self.err, f)
+ }
+}
+
+impl<T: Debug> error::Error for DisplayError<T> {}
+
+fn test_ptx_assert<'a, T: From<u8> + ze::SafeRepr + Debug + Copy + PartialEq>(
+ name: &str,
+ ptx_text: &'a str,
+ input: &[T],
+ output: &mut [T],
+) -> Result<(), Box<dyn error::Error + 'a>> {
+ let mut errors = Vec::new();
+ let ast = ptx::ModuleParser::new().parse(&mut errors, ptx_text)?;
+ assert!(errors.len() == 0);
+ let zluda_module = translate::to_spirv_module(ast)?;
+ let name = CString::new(name)?;
+ let result = run_spirv(name.as_c_str(), zluda_module, input, output)
+ .map_err(|err| DisplayError { err })?;
+ assert_eq!(result.as_slice(), output);
+ Ok(())
+}
+
+fn run_spirv<T: From<u8> + ze::SafeRepr + Copy + Debug>(
+ name: &CStr,
+ module: translate::Module,
+ input: &[T],
+ output: &mut [T],
+) -> ze::Result<Vec<T>> {
+ ze::init()?;
+ let spirv = module.spirv.assemble();
+ let byte_il = unsafe {
+ slice::from_raw_parts::<u8>(
+ spirv.as_ptr() as *const _,
+ spirv.len() * mem::size_of::<u32>(),
+ )
+ };
+ let use_shared_mem = module
+ .kernel_info
+ .get(name.to_str().unwrap())
+ .map(|info| info.uses_shared_mem)
+ .unwrap_or(false);
+ let mut result = vec![0u8.into(); output.len()];
+ {
+ let mut drivers = ze::Driver::get()?;
+ let drv = drivers.drain(0..1).next().unwrap();
+ let mut ctx = ze::Context::new(&drv)?;
+ let mut devices = drv.devices()?;
+ let dev = devices.drain(0..1).next().unwrap();
+ let queue = ze::CommandQueue::new(&mut ctx, &dev)?;
+ let (module, maybe_log) = match module.should_link_ptx_impl {
+ Some(ptx_impl) => ze::Module::build_link_spirv(
+ &mut ctx,
+ &dev,
+ &[ptx_impl, byte_il],
+ Some(module.build_options.as_c_str()),
+ ),
+ None => {
+ let (module, log) = ze::Module::build_spirv(
+ &mut ctx,
+ &dev,
+ byte_il,
+ Some(module.build_options.as_c_str()),
+ );
+ (module, Some(log))
+ }
+ };
+ let module = match module {
+ Ok(m) => m,
+ Err(err) => {
+ let raw_err_string = maybe_log
+ .map(|log| log.get_cstring())
+ .transpose()?
+ .unwrap_or(CString::default());
+ let err_string = raw_err_string.to_string_lossy();
+ panic!("{:?}\n{}", err, err_string);
+ }
+ };
+ let mut kernel = ze::Kernel::new_resident(&module, name)?;
+ kernel.set_indirect_access(
+ ze::sys::ze_kernel_indirect_access_flags_t::ZE_KERNEL_INDIRECT_ACCESS_FLAG_DEVICE,
+ )?;
+ let mut inp_b = ze::DeviceBuffer::<T>::new(&mut ctx, &dev, cmp::max(input.len(), 1))?;
+ let mut out_b = ze::DeviceBuffer::<T>::new(&mut ctx, &dev, cmp::max(output.len(), 1))?;
+ let inp_b_ptr_mut: ze::BufferPtrMut<T> = (&mut inp_b).into();
+ let event_pool = ze::EventPool::new(&mut ctx, 3, Some(&[&dev]))?;
+ let ev0 = ze::Event::new(&event_pool, 0)?;
+ let ev1 = ze::Event::new(&event_pool, 1)?;
+ let mut ev2 = ze::Event::new(&event_pool, 2)?;
+ let mut cmd_list = ze::CommandList::new(&mut ctx, &dev)?;
+ let out_b_ptr_mut: ze::BufferPtrMut<T> = (&mut out_b).into();
+ let mut init_evs = [ev0, ev1];
+ cmd_list.append_memory_copy(inp_b_ptr_mut, input, Some(&mut init_evs[0]), &mut [])?;
+ cmd_list.append_memory_fill(out_b_ptr_mut, 0, Some(&mut init_evs[1]), &mut [])?;
+ kernel.set_group_size(1, 1, 1)?;
+ kernel.set_arg_buffer(0, inp_b_ptr_mut)?;
+ kernel.set_arg_buffer(1, out_b_ptr_mut)?;
+ if use_shared_mem {
+ unsafe { kernel.set_arg_raw(2, 128, ptr::null())? };
+ }
+ cmd_list.append_launch_kernel(&kernel, &[1, 1, 1], Some(&mut ev2), &mut init_evs)?;
+ cmd_list.append_memory_copy(result.as_mut_slice(), out_b_ptr_mut, None, &mut [ev2])?;
+ queue.execute(cmd_list)?;
+ }
+ Ok(result)
+}
+
+fn test_spvtxt_assert<'a>(
+ ptx_txt: &'a str,
+ spirv_txt: &'a [u8],
+ spirv_file_name: &'a str,
+) -> Result<(), Box<dyn error::Error + 'a>> {
+ let mut errors = Vec::new();
+ let ast = ptx::ModuleParser::new().parse(&mut errors, ptx_txt)?;
+ assert!(errors.len() == 0);
+ let spirv_module = translate::to_spirv_module(ast)?;
+ let spv_context =
+ unsafe { spirv_tools::spvContextCreate(spv_target_env::SPV_ENV_UNIVERSAL_1_3) };
+ assert!(spv_context != ptr::null_mut());
+ let mut spv_binary: spv_binary = ptr::null_mut();
+ let result = unsafe {
+ spirv_tools::spvTextToBinary(
+ spv_context,
+ spirv_txt.as_ptr() as *const _,
+ spirv_txt.len(),
+ &mut spv_binary,
+ ptr::null_mut(),
+ )
+ };
+ if result != spv_result_t::SPV_SUCCESS {
+ panic!("{:?}\n{}", result, unsafe {
+ str::from_utf8_unchecked(spirv_txt)
+ });
+ }
+ let mut parsed_spirv = Vec::<u32>::new();
+ let result = unsafe {
+ spirv_tools::spvBinaryParse(
+ spv_context,
+ &mut parsed_spirv as *mut _ as *mut _,
+ (*spv_binary).code,
+ (*spv_binary).wordCount,
+ Some(parse_header_cb),
+ Some(parse_instruction_cb),
+ ptr::null_mut(),
+ )
+ };
+ assert!(result == spv_result_t::SPV_SUCCESS);
+ let mut loader = Loader::new();
+ rspirv::binary::parse_words(&parsed_spirv, &mut loader)?;
+ let spvtxt_mod = loader.module();
+ unsafe { spirv_tools::spvBinaryDestroy(spv_binary) };
+ if !is_spirv_fns_equal(&spirv_module.spirv.functions, &spvtxt_mod.functions) {
+ // We could simply use ptx_mod.disassemble, but SPIRV-Tools text formattinmg is so much nicer
+ let spv_from_ptx_binary = spirv_module.spirv.assemble();
+ let mut spv_text: spirv_tools::spv_text = ptr::null_mut();
+ let result = unsafe {
+ spirv_tools::spvBinaryToText(
+ spv_context,
+ spv_from_ptx_binary.as_ptr(),
+ spv_from_ptx_binary.len(),
+ (spirv_tools::spv_binary_to_text_options_t::SPV_BINARY_TO_TEXT_OPTION_INDENT | spirv_tools::spv_binary_to_text_options_t::SPV_BINARY_TO_TEXT_OPTION_NO_HEADER | spirv_tools::spv_binary_to_text_options_t::SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES).0,
+ &mut spv_text as *mut _,
+ ptr::null_mut()
+ )
+ };
+ unsafe { spirv_tools::spvContextDestroy(spv_context) };
+ let spirv_text = if result == spv_result_t::SPV_SUCCESS {
+ let raw_text = unsafe {
+ std::slice::from_raw_parts((*spv_text).str_ as *const u8, (*spv_text).length)
+ };
+ let spv_from_ptx_text = unsafe { str::from_utf8_unchecked(raw_text) };
+ // TODO: stop leaking kernel text
+ Cow::Borrowed(spv_from_ptx_text)
+ } else {
+ Cow::Owned(spirv_module.spirv.disassemble())
+ };
+ if let Ok(dump_path) = env::var("ZLUDA_TEST_SPIRV_DUMP_DIR") {
+ let mut path = PathBuf::from(dump_path);
+ if let Ok(()) = fs::create_dir_all(&path) {
+ path.push(spirv_file_name);
+ #[allow(unused_must_use)]
+ {
+ fs::write(path, spirv_text.as_bytes());
+ }
+ }
+ }
+ panic!(spirv_text.to_string());
+ }
+ unsafe { spirv_tools::spvContextDestroy(spv_context) };
+ Ok(())
+}
+
+struct EqMap<T>
+where
+ T: Eq + Copy + Hash,
+{
+ m1: HashMap<T, T>,
+ m2: HashMap<T, T>,
+}
+
+impl<T: Copy + Eq + Hash> EqMap<T> {
+ fn new() -> Self {
+ EqMap {
+ m1: HashMap::new(),
+ m2: HashMap::new(),
+ }
+ }
+
+ fn is_equal(&mut self, t1: T, t2: T) -> bool {
+ match (self.m1.entry(t1), self.m2.entry(t2)) {
+ (Entry::Occupied(entry1), Entry::Occupied(entry2)) => {
+ *entry1.get() == t2 && *entry2.get() == t1
+ }
+ (Entry::Vacant(entry1), Entry::Vacant(entry2)) => {
+ entry1.insert(t2);
+ entry2.insert(t1);
+ true
+ }
+ _ => false,
+ }
+ }
+}
+
+fn is_spirv_fns_equal(fns1: &[Function], fns2: &[Function]) -> bool {
+ if fns1.len() != fns2.len() {
+ return false;
+ }
+ for (fn1, fn2) in fns1.iter().zip(fns2.iter()) {
+ if !is_spirv_fn_equal(fn1, fn2) {
+ return false;
+ }
+ }
+ true
+}
+
+fn is_spirv_fn_equal(fn1: &Function, fn2: &Function) -> bool {
+ let mut map = EqMap::new();
+ if !is_option_equal(&fn1.def, &fn2.def, &mut map, is_instr_equal) {
+ return false;
+ }
+ if !is_option_equal(&fn1.end, &fn2.end, &mut map, is_instr_equal) {
+ return false;
+ }
+ if fn1.parameters.len() != fn2.parameters.len() {
+ return false;
+ }
+ for (inst1, inst2) in fn1.parameters.iter().zip(fn2.parameters.iter()) {
+ if !is_instr_equal(inst1, inst2, &mut map) {
+ return false;
+ }
+ }
+ if fn1.blocks.len() != fn2.blocks.len() {
+ return false;
+ }
+ for (b1, b2) in fn1.blocks.iter().zip(fn2.blocks.iter()) {
+ if !is_block_equal(b1, b2, &mut map) {
+ return false;
+ }
+ }
+ true
+}
+
+fn is_block_equal(b1: &Block, b2: &Block, map: &mut EqMap<Word>) -> bool {
+ if !is_option_equal(&b1.label, &b2.label, map, is_instr_equal) {
+ return false;
+ }
+ if b1.instructions.len() != b2.instructions.len() {
+ return false;
+ }
+ for (inst1, inst2) in b1.instructions.iter().zip(b2.instructions.iter()) {
+ if !is_instr_equal(inst1, inst2, map) {
+ return false;
+ }
+ }
+ true
+}
+
+fn is_instr_equal(instr1: &Instruction, instr2: &Instruction, map: &mut EqMap<Word>) -> bool {
+ if instr1.class.opcode != instr2.class.opcode {
+ return false;
+ }
+ if !is_option_equal(&instr1.result_type, &instr2.result_type, map, is_word_equal) {
+ return false;
+ }
+ if !is_option_equal(&instr1.result_id, &instr2.result_id, map, is_word_equal) {
+ return false;
+ }
+ if instr1.operands.len() != instr2.operands.len() {
+ return false;
+ }
+ for (o1, o2) in instr1.operands.iter().zip(instr2.operands.iter()) {
+ match (o1, o2) {
+ (Operand::IdMemorySemantics(w1), Operand::IdMemorySemantics(w2)) => {
+ if !is_word_equal(w1, w2, map) {
+ return false;
+ }
+ }
+ (Operand::IdScope(w1), Operand::IdScope(w2)) => {
+ if !is_word_equal(w1, w2, map) {
+ return false;
+ }
+ }
+ (Operand::IdRef(w1), Operand::IdRef(w2)) => {
+ if !is_word_equal(w1, w2, map) {
+ return false;
+ }
+ }
+ (o1, o2) => {
+ if o1 != o2 {
+ return false;
+ }
+ }
+ }
+ }
+ true
+}
+
+fn is_word_equal(t1: &Word, t2: &Word, map: &mut EqMap<Word>) -> bool {
+ map.is_equal(*t1, *t2)
+}
+
+fn is_option_equal<T, F: FnOnce(&T, &T, &mut EqMap<Word>) -> bool>(
+ o1: &Option<T>,
+ o2: &Option<T>,
+ map: &mut EqMap<Word>,
+ f: F,
+) -> bool {
+ match (o1, o2) {
+ (Some(t1), Some(t2)) => f(t1, t2, map),
+ (None, None) => true,
+ _ => panic!(),
+ }
+}
+
+unsafe extern "C" fn parse_header_cb(
+ user_data: *mut c_void,
+ endian: spv_endianness_t,
+ magic: u32,
+ version: u32,
+ generator: u32,
+ id_bound: u32,
+ reserved: u32,
+) -> spv_result_t {
+ if endian == spv_endianness_t::SPV_ENDIANNESS_BIG {
+ return spv_result_t::SPV_UNSUPPORTED;
+ }
+ let result_vec: &mut Vec<u32> = std::mem::transmute(user_data);
+ result_vec.push(magic);
+ result_vec.push(version);
+ result_vec.push(generator);
+ result_vec.push(id_bound);
+ result_vec.push(reserved);
+ spv_result_t::SPV_SUCCESS
+}
+
+unsafe extern "C" fn parse_instruction_cb(
+ user_data: *mut c_void,
+ inst: *const spv_parsed_instruction_t,
+) -> spv_result_t {
+ let inst = &*inst;
+ let result_vec: &mut Vec<u32> = std::mem::transmute(user_data);
+ for i in 0..inst.num_words {
+ result_vec.push(*(inst.words.add(i as usize)));
+ }
+ spv_result_t::SPV_SUCCESS
+}
diff --git a/ptx/src/test/spirv_run/mov.ptx b/ptx/src/test/spirv_run/mov.ptx
new file mode 100644
index 0000000..5ca61f1
--- /dev/null
+++ b/ptx/src/test/spirv_run/mov.ptx
@@ -0,0 +1,22 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry mov(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp;
+ .reg .u64 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u64 temp, [in_addr];
+ mov.u64 temp2, temp;
+ st.u64 [out_addr], temp2;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/mov.spvtxt b/ptx/src/test/spirv_run/mov.spvtxt
new file mode 100644
index 0000000..15118aa
--- /dev/null
+++ b/ptx/src/test/spirv_run/mov.spvtxt
@@ -0,0 +1,46 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %22 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "mov"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %25 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %1 = OpFunction %void None %25
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %20 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %18 = OpConvertUToPtr %_ptr_Generic_ulong %13
+ %12 = OpLoad %ulong %18
+ OpStore %6 %12
+ %15 = OpLoad %ulong %6
+ %14 = OpCopyObject %ulong %15
+ OpStore %7 %14
+ %16 = OpLoad %ulong %5
+ %17 = OpLoad %ulong %7
+ %19 = OpConvertUToPtr %_ptr_Generic_ulong %16
+ OpStore %19 %17
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/mov_address.ptx b/ptx/src/test/spirv_run/mov_address.ptx
new file mode 100644
index 0000000..433fc0e
--- /dev/null
+++ b/ptx/src/test/spirv_run/mov_address.ptx
@@ -0,0 +1,15 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry mov_address(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .local .b8 __local_depot0[8];
+ .reg .u64 temp;
+
+ mov.u64 temp, __local_depot0;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/mov_address.spvtxt b/ptx/src/test/spirv_run/mov_address.spvtxt
new file mode 100644
index 0000000..26ae21f
--- /dev/null
+++ b/ptx/src/test/spirv_run/mov_address.spvtxt
@@ -0,0 +1,33 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int64
+ OpCapability Int8
+ %12 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "mov_address"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %15 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uchar = OpTypeInt 8 0
+ %uint = OpTypeInt 32 0
+ %uint_8 = OpConstant %uint 8
+%_arr_uchar_uint_8 = OpTypeArray %uchar %uint_8
+%_ptr_Function__arr_uchar_uint_8 = OpTypePointer Function %_arr_uchar_uint_8
+ %1 = OpFunction %void None %15
+ %6 = OpFunctionParameter %ulong
+ %7 = OpFunctionParameter %ulong
+ %10 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function__arr_uchar_uint_8 Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %6
+ OpStore %3 %7
+ %9 = OpConvertPtrToU %ulong %4
+ %8 = OpCopyObject %ulong %9
+ OpStore %5 %8
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/mul_ftz.ptx b/ptx/src/test/spirv_run/mul_ftz.ptx
new file mode 100644
index 0000000..eb24215
--- /dev/null
+++ b/ptx/src/test/spirv_run/mul_ftz.ptx
@@ -0,0 +1,23 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry mul_ftz(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .f32 temp1;
+ .reg .f32 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.f32 temp1, [in_addr];
+ ld.f32 temp2, [in_addr+4];
+ mul.ftz.f32 temp1, temp1, temp2;
+ st.f32 [out_addr], temp1;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/mul_ftz.spvtxt b/ptx/src/test/spirv_run/mul_ftz.spvtxt
new file mode 100644
index 0000000..3e80ae3
--- /dev/null
+++ b/ptx/src/test/spirv_run/mul_ftz.spvtxt
@@ -0,0 +1,55 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %28 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "mul_ftz"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %31 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+%_ptr_Generic_float = OpTypePointer Generic %float
+ %ulong_4 = OpConstant %ulong 4
+ %1 = OpFunction %void None %31
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %26 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_float Function
+ %7 = OpVariable %_ptr_Function_float Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %23 = OpConvertUToPtr %_ptr_Generic_float %13
+ %12 = OpLoad %float %23
+ OpStore %6 %12
+ %15 = OpLoad %ulong %4
+ %22 = OpIAdd %ulong %15 %ulong_4
+ %24 = OpConvertUToPtr %_ptr_Generic_float %22
+ %14 = OpLoad %float %24
+ OpStore %7 %14
+ %17 = OpLoad %float %6
+ %18 = OpLoad %float %7
+ %16 = OpFMul %float %17 %18
+ OpStore %6 %16
+ %19 = OpLoad %ulong %5
+ %20 = OpLoad %float %6
+ %25 = OpConvertUToPtr %_ptr_Generic_float %19
+ OpStore %25 %20
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/mul_hi.ptx b/ptx/src/test/spirv_run/mul_hi.ptx
new file mode 100644
index 0000000..1dc1572
--- /dev/null
+++ b/ptx/src/test/spirv_run/mul_hi.ptx
@@ -0,0 +1,22 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry mul_hi(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp;
+ .reg .u64 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u64 temp, [in_addr];
+ mul.hi.u64 temp2, temp, 2;
+ st.u64 [out_addr], temp2;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/mul_hi.spvtxt b/ptx/src/test/spirv_run/mul_hi.spvtxt
new file mode 100644
index 0000000..8449183
--- /dev/null
+++ b/ptx/src/test/spirv_run/mul_hi.spvtxt
@@ -0,0 +1,47 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %23 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "mul_hi"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %26 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %ulong_2 = OpConstant %ulong 2
+ %1 = OpFunction %void None %26
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %21 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %19 = OpConvertUToPtr %_ptr_Generic_ulong %13
+ %12 = OpLoad %ulong %19
+ OpStore %6 %12
+ %15 = OpLoad %ulong %6
+ %14 = OpExtInst %ulong %23 u_mul_hi %15 %ulong_2
+ OpStore %7 %14
+ %16 = OpLoad %ulong %5
+ %17 = OpLoad %ulong %7
+ %20 = OpConvertUToPtr %_ptr_Generic_ulong %16
+ OpStore %20 %17
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/mul_lo.ptx b/ptx/src/test/spirv_run/mul_lo.ptx
new file mode 100644
index 0000000..cae3b57
--- /dev/null
+++ b/ptx/src/test/spirv_run/mul_lo.ptx
@@ -0,0 +1,22 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry mul_lo(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp;
+ .reg .u64 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u64 temp, [in_addr];
+ mul.lo.u64 temp2, temp, 2;
+ st.u64 [out_addr], temp2;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/mul_lo.spvtxt b/ptx/src/test/spirv_run/mul_lo.spvtxt
new file mode 100644
index 0000000..d4b2566
--- /dev/null
+++ b/ptx/src/test/spirv_run/mul_lo.spvtxt
@@ -0,0 +1,47 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %23 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "mul_lo"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %26 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %ulong_2 = OpConstant %ulong 2
+ %1 = OpFunction %void None %26
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %21 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %19 = OpConvertUToPtr %_ptr_Generic_ulong %13
+ %12 = OpLoad %ulong %19
+ OpStore %6 %12
+ %15 = OpLoad %ulong %6
+ %14 = OpIMul %ulong %15 %ulong_2
+ OpStore %7 %14
+ %16 = OpLoad %ulong %5
+ %17 = OpLoad %ulong %7
+ %20 = OpConvertUToPtr %_ptr_Generic_ulong %16
+ OpStore %20 %17
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/mul_non_ftz.ptx b/ptx/src/test/spirv_run/mul_non_ftz.ptx
new file mode 100644
index 0000000..31cd14c
--- /dev/null
+++ b/ptx/src/test/spirv_run/mul_non_ftz.ptx
@@ -0,0 +1,23 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry mul_non_ftz(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .f32 temp1;
+ .reg .f32 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.f32 temp1, [in_addr];
+ ld.f32 temp2, [in_addr+4];
+ mul.f32 temp1, temp1, temp2;
+ st.f32 [out_addr], temp1;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/mul_non_ftz.spvtxt b/ptx/src/test/spirv_run/mul_non_ftz.spvtxt
new file mode 100644
index 0000000..cb20943
--- /dev/null
+++ b/ptx/src/test/spirv_run/mul_non_ftz.spvtxt
@@ -0,0 +1,55 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %28 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "mul_non_ftz"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %31 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+%_ptr_Generic_float = OpTypePointer Generic %float
+ %ulong_4 = OpConstant %ulong 4
+ %1 = OpFunction %void None %31
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %26 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_float Function
+ %7 = OpVariable %_ptr_Function_float Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %23 = OpConvertUToPtr %_ptr_Generic_float %13
+ %12 = OpLoad %float %23
+ OpStore %6 %12
+ %15 = OpLoad %ulong %4
+ %22 = OpIAdd %ulong %15 %ulong_4
+ %24 = OpConvertUToPtr %_ptr_Generic_float %22
+ %14 = OpLoad %float %24
+ OpStore %7 %14
+ %17 = OpLoad %float %6
+ %18 = OpLoad %float %7
+ %16 = OpFMul %float %17 %18
+ OpStore %6 %16
+ %19 = OpLoad %ulong %5
+ %20 = OpLoad %float %6
+ %25 = OpConvertUToPtr %_ptr_Generic_float %19
+ OpStore %25 %20
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/mul_wide.ptx b/ptx/src/test/spirv_run/mul_wide.ptx
new file mode 100644
index 0000000..2d6f8a5
--- /dev/null
+++ b/ptx/src/test/spirv_run/mul_wide.ptx
@@ -0,0 +1,24 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry mul_wide(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .s32 inp1;
+ .reg .s32 inp2;
+ .reg .s64 result;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.global.s32 inp1, [in_addr];
+ ld.global.s32 inp2, [in_addr+4];
+ mul.wide.s32 result, inp1, inp2;
+ st.u64 [out_addr], result;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/mul_wide.spvtxt b/ptx/src/test/spirv_run/mul_wide.spvtxt
new file mode 100644
index 0000000..632fa3b
--- /dev/null
+++ b/ptx/src/test/spirv_run/mul_wide.spvtxt
@@ -0,0 +1,64 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %30 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "mul_wide"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %33 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_CrossWorkgroup_uint = OpTypePointer CrossWorkgroup %uint
+ %ulong_4 = OpConstant %ulong 4
+ %_struct_38 = OpTypeStruct %uint %uint
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %1 = OpFunction %void None %33
+ %9 = OpFunctionParameter %ulong
+ %10 = OpFunctionParameter %ulong
+ %28 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ %7 = OpVariable %_ptr_Function_uint Function
+ %8 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %9
+ OpStore %3 %10
+ %11 = OpLoad %ulong %2
+ OpStore %4 %11
+ %12 = OpLoad %ulong %3
+ OpStore %5 %12
+ %14 = OpLoad %ulong %4
+ %24 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %14
+ %13 = OpLoad %uint %24
+ OpStore %6 %13
+ %16 = OpLoad %ulong %4
+ %23 = OpIAdd %ulong %16 %ulong_4
+ %25 = OpConvertUToPtr %_ptr_CrossWorkgroup_uint %23
+ %15 = OpLoad %uint %25
+ OpStore %7 %15
+ %18 = OpLoad %uint %6
+ %19 = OpLoad %uint %7
+ %39 = OpSMulExtended %_struct_38 %18 %19
+ %40 = OpCompositeExtract %uint %39 0
+ %41 = OpCompositeExtract %uint %39 1
+ %43 = OpCompositeConstruct %v2uint %40 %41
+ %17 = OpBitcast %ulong %43
+ OpStore %8 %17
+ %20 = OpLoad %ulong %5
+ %21 = OpLoad %ulong %8
+ %26 = OpConvertUToPtr %_ptr_Generic_ulong %20
+ %27 = OpCopyObject %ulong %21
+ OpStore %26 %27
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/neg.ptx b/ptx/src/test/spirv_run/neg.ptx
new file mode 100644
index 0000000..60fe162
--- /dev/null
+++ b/ptx/src/test/spirv_run/neg.ptx
@@ -0,0 +1,21 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry neg(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .s32 temp1;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.s32 temp1, [in_addr];
+ neg.s32 temp1, temp1;
+ st.s32 [out_addr], temp1;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/neg.spvtxt b/ptx/src/test/spirv_run/neg.spvtxt
new file mode 100644
index 0000000..50726aa
--- /dev/null
+++ b/ptx/src/test/spirv_run/neg.spvtxt
@@ -0,0 +1,47 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %21 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "neg"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %24 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %1 = OpFunction %void None %24
+ %7 = OpFunctionParameter %ulong
+ %8 = OpFunctionParameter %ulong
+ %19 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %7
+ OpStore %3 %8
+ %9 = OpLoad %ulong %2
+ OpStore %4 %9
+ %10 = OpLoad %ulong %3
+ OpStore %5 %10
+ %12 = OpLoad %ulong %4
+ %17 = OpConvertUToPtr %_ptr_Generic_uint %12
+ %11 = OpLoad %uint %17
+ OpStore %6 %11
+ %14 = OpLoad %uint %6
+ %13 = OpSNegate %uint %14
+ OpStore %6 %13
+ %15 = OpLoad %ulong %5
+ %16 = OpLoad %uint %6
+ %18 = OpConvertUToPtr %_ptr_Generic_uint %15
+ OpStore %18 %16
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/not.ptx b/ptx/src/test/spirv_run/not.ptx
new file mode 100644
index 0000000..6182134
--- /dev/null
+++ b/ptx/src/test/spirv_run/not.ptx
@@ -0,0 +1,22 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry not(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp;
+ .reg .u64 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u64 temp, [in_addr];
+ not.b64 temp2, temp;
+ st.u64 [out_addr], temp2;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/not.spvtxt b/ptx/src/test/spirv_run/not.spvtxt
new file mode 100644
index 0000000..d6bc389
--- /dev/null
+++ b/ptx/src/test/spirv_run/not.spvtxt
@@ -0,0 +1,48 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %24 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "not"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %27 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %1 = OpFunction %void None %27
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %22 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %18 = OpConvertUToPtr %_ptr_Generic_ulong %13
+ %12 = OpLoad %ulong %18
+ OpStore %6 %12
+ %15 = OpLoad %ulong %6
+ %20 = OpCopyObject %ulong %15
+ %19 = OpNot %ulong %20
+ %14 = OpCopyObject %ulong %19
+ OpStore %7 %14
+ %16 = OpLoad %ulong %5
+ %17 = OpLoad %ulong %7
+ %21 = OpConvertUToPtr %_ptr_Generic_ulong %16
+ OpStore %21 %17
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/ntid.ptx b/ptx/src/test/spirv_run/ntid.ptx
new file mode 100644
index 0000000..2961197
--- /dev/null
+++ b/ptx/src/test/spirv_run/ntid.ptx
@@ -0,0 +1,23 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry ntid(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u32 in_val;
+ .reg .u32 global_count;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u32 in_val, [in_addr];
+ mov.u32 global_count, %ntid.x;
+ add.u32 in_val, in_val, global_count;
+ st.u32 [out_addr], in_val;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/ntid.spvtxt b/ptx/src/test/spirv_run/ntid.spvtxt
new file mode 100644
index 0000000..acd69d7
--- /dev/null
+++ b/ptx/src/test/spirv_run/ntid.spvtxt
@@ -0,0 +1,59 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %27 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "ntid" %gl_WorkGroupSize
+ OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %v3ulong = OpTypeVector %ulong 3
+%_ptr_Input_v3ulong = OpTypePointer Input %v3ulong
+%gl_WorkGroupSize = OpVariable %_ptr_Input_v3ulong Input
+ %32 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %1 = OpFunction %void None %32
+ %9 = OpFunctionParameter %ulong
+ %10 = OpFunctionParameter %ulong
+ %25 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ %7 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %9
+ OpStore %3 %10
+ %11 = OpLoad %ulong %2
+ OpStore %4 %11
+ %12 = OpLoad %ulong %3
+ OpStore %5 %12
+ %14 = OpLoad %ulong %4
+ %23 = OpConvertUToPtr %_ptr_Generic_uint %14
+ %13 = OpLoad %uint %23
+ OpStore %6 %13
+ %37 = OpLoad %v3ulong %gl_WorkGroupSize
+ %22 = OpCompositeExtract %ulong %37 0
+ %38 = OpBitcast %ulong %22
+ %16 = OpUConvert %uint %38
+ %15 = OpCopyObject %uint %16
+ OpStore %7 %15
+ %18 = OpLoad %uint %6
+ %19 = OpLoad %uint %7
+ %17 = OpIAdd %uint %18 %19
+ OpStore %6 %17
+ %20 = OpLoad %ulong %5
+ %21 = OpLoad %uint %6
+ %24 = OpConvertUToPtr %_ptr_Generic_uint %20
+ OpStore %24 %21
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/or.ptx b/ptx/src/test/spirv_run/or.ptx
new file mode 100644
index 0000000..1deb3c8
--- /dev/null
+++ b/ptx/src/test/spirv_run/or.ptx
@@ -0,0 +1,23 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry or(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp1;
+ .reg .u64 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u64 temp1, [in_addr];
+ ld.u64 temp2, [in_addr+8];
+ or.b64 temp1, temp1, temp2;
+ st.u64 [out_addr], temp1;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/or.spvtxt b/ptx/src/test/spirv_run/or.spvtxt
new file mode 100644
index 0000000..312b1b3
--- /dev/null
+++ b/ptx/src/test/spirv_run/or.spvtxt
@@ -0,0 +1,56 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %31 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "or"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %34 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %ulong_8 = OpConstant %ulong 8
+ %1 = OpFunction %void None %34
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %29 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %23 = OpConvertUToPtr %_ptr_Generic_ulong %13
+ %12 = OpLoad %ulong %23
+ OpStore %6 %12
+ %15 = OpLoad %ulong %4
+ %22 = OpIAdd %ulong %15 %ulong_8
+ %24 = OpConvertUToPtr %_ptr_Generic_ulong %22
+ %14 = OpLoad %ulong %24
+ OpStore %7 %14
+ %17 = OpLoad %ulong %6
+ %18 = OpLoad %ulong %7
+ %26 = OpCopyObject %ulong %17
+ %27 = OpCopyObject %ulong %18
+ %25 = OpBitwiseOr %ulong %26 %27
+ %16 = OpCopyObject %ulong %25
+ OpStore %6 %16
+ %19 = OpLoad %ulong %5
+ %20 = OpLoad %ulong %6
+ %28 = OpConvertUToPtr %_ptr_Generic_ulong %19
+ OpStore %28 %20
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/popc.ptx b/ptx/src/test/spirv_run/popc.ptx
new file mode 100644
index 0000000..7106422
--- /dev/null
+++ b/ptx/src/test/spirv_run/popc.ptx
@@ -0,0 +1,21 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry popc(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .b32 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.b32 temp, [in_addr];
+ popc.b32 temp, temp;
+ st.b32 [out_addr], temp;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/popc.spvtxt b/ptx/src/test/spirv_run/popc.spvtxt
new file mode 100644
index 0000000..bb4968f
--- /dev/null
+++ b/ptx/src/test/spirv_run/popc.spvtxt
@@ -0,0 +1,47 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %21 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "popc"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %24 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %1 = OpFunction %void None %24
+ %7 = OpFunctionParameter %ulong
+ %8 = OpFunctionParameter %ulong
+ %19 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %7
+ OpStore %3 %8
+ %9 = OpLoad %ulong %2
+ OpStore %4 %9
+ %10 = OpLoad %ulong %3
+ OpStore %5 %10
+ %12 = OpLoad %ulong %4
+ %17 = OpConvertUToPtr %_ptr_Generic_uint %12
+ %11 = OpLoad %uint %17
+ OpStore %6 %11
+ %14 = OpLoad %uint %6
+ %13 = OpBitCount %uint %14
+ OpStore %6 %13
+ %15 = OpLoad %ulong %5
+ %16 = OpLoad %uint %6
+ %18 = OpConvertUToPtr %_ptr_Generic_uint %15
+ OpStore %18 %16
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/pred_not.ptx b/ptx/src/test/spirv_run/pred_not.ptx
new file mode 100644
index 0000000..e058470
--- /dev/null
+++ b/ptx/src/test/spirv_run/pred_not.ptx
@@ -0,0 +1,28 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry pred_not(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp;
+ .reg .u64 temp2;
+ .reg .u64 temp3;
+ .reg .pred pred;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u64 temp, [in_addr];
+ ld.u64 temp2, [in_addr + 8];
+ setp.lt.u64 pred, temp, temp2;
+ not.pred pred, pred;
+ @pred mov.u64 temp3, 1;
+ @!pred mov.u64 temp3, 2;
+ st.u64 [out_addr], temp3;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/pred_not.spvtxt b/ptx/src/test/spirv_run/pred_not.spvtxt
new file mode 100644
index 0000000..178c98f
--- /dev/null
+++ b/ptx/src/test/spirv_run/pred_not.spvtxt
@@ -0,0 +1,78 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %42 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "pred_not"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %45 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %bool = OpTypeBool
+%_ptr_Function_bool = OpTypePointer Function %bool
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %ulong_8 = OpConstant %ulong 8
+ %true = OpConstantTrue %bool
+ %false = OpConstantFalse %bool
+ %ulong_1 = OpConstant %ulong 1
+ %ulong_2 = OpConstant %ulong 2
+ %1 = OpFunction %void None %45
+ %14 = OpFunctionParameter %ulong
+ %15 = OpFunctionParameter %ulong
+ %40 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ %8 = OpVariable %_ptr_Function_ulong Function
+ %9 = OpVariable %_ptr_Function_bool Function
+ OpStore %2 %14
+ OpStore %3 %15
+ %16 = OpLoad %ulong %2
+ OpStore %4 %16
+ %17 = OpLoad %ulong %3
+ OpStore %5 %17
+ %19 = OpLoad %ulong %4
+ %37 = OpConvertUToPtr %_ptr_Generic_ulong %19
+ %18 = OpLoad %ulong %37
+ OpStore %6 %18
+ %21 = OpLoad %ulong %4
+ %34 = OpIAdd %ulong %21 %ulong_8
+ %38 = OpConvertUToPtr %_ptr_Generic_ulong %34
+ %20 = OpLoad %ulong %38
+ OpStore %7 %20
+ %23 = OpLoad %ulong %6
+ %24 = OpLoad %ulong %7
+ %22 = OpULessThan %bool %23 %24
+ OpStore %9 %22
+ %26 = OpLoad %bool %9
+ %25 = OpSelect %bool %26 %false %true
+ OpStore %9 %25
+ %27 = OpLoad %bool %9
+ OpBranchConditional %27 %10 %11
+ %10 = OpLabel
+ %28 = OpCopyObject %ulong %ulong_1
+ OpStore %8 %28
+ OpBranch %11
+ %11 = OpLabel
+ %29 = OpLoad %bool %9
+ OpBranchConditional %29 %13 %12
+ %12 = OpLabel
+ %30 = OpCopyObject %ulong %ulong_2
+ OpStore %8 %30
+ OpBranch %13
+ %13 = OpLabel
+ %31 = OpLoad %ulong %5
+ %32 = OpLoad %ulong %8
+ %39 = OpConvertUToPtr %_ptr_Generic_ulong %31
+ OpStore %39 %32
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/rcp.ptx b/ptx/src/test/spirv_run/rcp.ptx
new file mode 100644
index 0000000..eb02d7e
--- /dev/null
+++ b/ptx/src/test/spirv_run/rcp.ptx
@@ -0,0 +1,21 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry rcp(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .f32 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.f32 temp, [in_addr];
+ rcp.approx.f32 temp, temp;
+ st.f32 [out_addr], temp;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/rcp.spvtxt b/ptx/src/test/spirv_run/rcp.spvtxt
new file mode 100644
index 0000000..0ce2d75
--- /dev/null
+++ b/ptx/src/test/spirv_run/rcp.spvtxt
@@ -0,0 +1,49 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %21 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "rcp"
+ OpDecorate %13 FPFastMathMode AllowRecip
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %24 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+%_ptr_Generic_float = OpTypePointer Generic %float
+ %float_1 = OpConstant %float 1
+ %1 = OpFunction %void None %24
+ %7 = OpFunctionParameter %ulong
+ %8 = OpFunctionParameter %ulong
+ %19 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_float Function
+ OpStore %2 %7
+ OpStore %3 %8
+ %9 = OpLoad %ulong %2
+ OpStore %4 %9
+ %10 = OpLoad %ulong %3
+ OpStore %5 %10
+ %12 = OpLoad %ulong %4
+ %17 = OpConvertUToPtr %_ptr_Generic_float %12
+ %11 = OpLoad %float %17
+ OpStore %6 %11
+ %14 = OpLoad %float %6
+ %13 = OpFDiv %float %float_1 %14
+ OpStore %6 %13
+ %15 = OpLoad %ulong %5
+ %16 = OpLoad %float %6
+ %18 = OpConvertUToPtr %_ptr_Generic_float %15
+ OpStore %18 %16
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/reg_local.ptx b/ptx/src/test/spirv_run/reg_local.ptx
new file mode 100644
index 0000000..5707cea
--- /dev/null
+++ b/ptx/src/test/spirv_run/reg_local.ptx
@@ -0,0 +1,23 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry reg_local(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .local .align 8 .b8 local_x[8];
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .b64 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.global.u64 temp, [in_addr];
+ st.u64 [local_x], temp + 1;
+ ld.u64 temp, [local_x+0];
+ st.global.u64 [out_addr+0], temp;
+ ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/reg_local.spvtxt b/ptx/src/test/spirv_run/reg_local.spvtxt
new file mode 100644
index 0000000..5ce3689
--- /dev/null
+++ b/ptx/src/test/spirv_run/reg_local.spvtxt
@@ -0,0 +1,69 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %34 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "reg_local"
+ OpDecorate %4 Alignment 8
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %37 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+ %uchar = OpTypeInt 8 0
+ %uint_8 = OpConstant %uint 8
+%_arr_uchar_uint_8 = OpTypeArray %uchar %uint_8
+%_ptr_Function__arr_uchar_uint_8 = OpTypePointer Function %_arr_uchar_uint_8
+%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong
+ %ulong_1 = OpConstant %ulong 1
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %ulong_0 = OpConstant %ulong 0
+%_ptr_Generic_uchar = OpTypePointer Generic %uchar
+ %ulong_0_0 = OpConstant %ulong 0
+ %1 = OpFunction %void None %37
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %32 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function__arr_uchar_uint_8 Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %5 %10
+ %11 = OpLoad %ulong %3
+ OpStore %6 %11
+ %13 = OpLoad %ulong %5
+ %25 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %13
+ %24 = OpLoad %ulong %25
+ %12 = OpCopyObject %ulong %24
+ OpStore %7 %12
+ %14 = OpLoad %ulong %7
+ %26 = OpCopyObject %ulong %14
+ %19 = OpIAdd %ulong %26 %ulong_1
+ %27 = OpBitcast %_ptr_Generic_ulong %4
+ OpStore %27 %19
+ %28 = OpBitcast %_ptr_Generic_ulong %4
+ %47 = OpBitcast %_ptr_Generic_uchar %28
+ %48 = OpInBoundsPtrAccessChain %_ptr_Generic_uchar %47 %ulong_0
+ %21 = OpBitcast %_ptr_Generic_ulong %48
+ %29 = OpLoad %ulong %21
+ %15 = OpCopyObject %ulong %29
+ OpStore %7 %15
+ %16 = OpLoad %ulong %6
+ %17 = OpLoad %ulong %7
+ %23 = OpIAdd %ulong %16 %ulong_0_0
+ %30 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %23
+ %31 = OpCopyObject %ulong %17
+ OpStore %30 %31
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/rem.ptx b/ptx/src/test/spirv_run/rem.ptx
new file mode 100644
index 0000000..2ac482d
--- /dev/null
+++ b/ptx/src/test/spirv_run/rem.ptx
@@ -0,0 +1,23 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry rem(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .s32 temp1;
+ .reg .s32 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.s32 temp1, [in_addr];
+ ld.s32 temp2, [in_addr+4];
+ rem.s32 temp1, temp1, temp2;
+ st.s32 [out_addr], temp1;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/rem.spvtxt b/ptx/src/test/spirv_run/rem.spvtxt
new file mode 100644
index 0000000..72d0965
--- /dev/null
+++ b/ptx/src/test/spirv_run/rem.spvtxt
@@ -0,0 +1,55 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %28 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "rem"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %31 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %ulong_4 = OpConstant %ulong 4
+ %1 = OpFunction %void None %31
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %26 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ %7 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %23 = OpConvertUToPtr %_ptr_Generic_uint %13
+ %12 = OpLoad %uint %23
+ OpStore %6 %12
+ %15 = OpLoad %ulong %4
+ %22 = OpIAdd %ulong %15 %ulong_4
+ %24 = OpConvertUToPtr %_ptr_Generic_uint %22
+ %14 = OpLoad %uint %24
+ OpStore %7 %14
+ %17 = OpLoad %uint %6
+ %18 = OpLoad %uint %7
+ %16 = OpSMod %uint %17 %18
+ OpStore %6 %16
+ %19 = OpLoad %ulong %5
+ %20 = OpLoad %uint %6
+ %25 = OpConvertUToPtr %_ptr_Generic_uint %19
+ OpStore %25 %20
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/rsqrt.ptx b/ptx/src/test/spirv_run/rsqrt.ptx
new file mode 100644
index 0000000..5821501
--- /dev/null
+++ b/ptx/src/test/spirv_run/rsqrt.ptx
@@ -0,0 +1,21 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry rsqrt(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .f64 temp1;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.f64 temp1, [in_addr];
+ rsqrt.approx.f64 temp1, temp1;
+ st.f64 [out_addr], temp1;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/rsqrt.spvtxt b/ptx/src/test/spirv_run/rsqrt.spvtxt
new file mode 100644
index 0000000..ed473bc
--- /dev/null
+++ b/ptx/src/test/spirv_run/rsqrt.spvtxt
@@ -0,0 +1,47 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %21 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "rsqrt"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %24 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %double = OpTypeFloat 64
+%_ptr_Function_double = OpTypePointer Function %double
+%_ptr_Generic_double = OpTypePointer Generic %double
+ %1 = OpFunction %void None %24
+ %7 = OpFunctionParameter %ulong
+ %8 = OpFunctionParameter %ulong
+ %19 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_double Function
+ OpStore %2 %7
+ OpStore %3 %8
+ %9 = OpLoad %ulong %2
+ OpStore %4 %9
+ %10 = OpLoad %ulong %3
+ OpStore %5 %10
+ %12 = OpLoad %ulong %4
+ %17 = OpConvertUToPtr %_ptr_Generic_double %12
+ %11 = OpLoad %double %17
+ OpStore %6 %11
+ %14 = OpLoad %double %6
+ %13 = OpExtInst %double %21 native_rsqrt %14
+ OpStore %6 %13
+ %15 = OpLoad %ulong %5
+ %16 = OpLoad %double %6
+ %18 = OpConvertUToPtr %_ptr_Generic_double %15
+ OpStore %18 %16
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/selp.ptx b/ptx/src/test/spirv_run/selp.ptx
new file mode 100644
index 0000000..79171dc
--- /dev/null
+++ b/ptx/src/test/spirv_run/selp.ptx
@@ -0,0 +1,23 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry selp(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u16 temp1;
+ .reg .u16 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u16 temp1, [in_addr];
+ ld.u16 temp2, [in_addr + 2];
+ selp.u16 temp1, temp1, temp2, 0;
+ st.u16 [out_addr], temp1;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/selp.spvtxt b/ptx/src/test/spirv_run/selp.spvtxt
new file mode 100644
index 0000000..84976ac
--- /dev/null
+++ b/ptx/src/test/spirv_run/selp.spvtxt
@@ -0,0 +1,57 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %29 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "selp"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %32 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %ushort = OpTypeInt 16 0
+%_ptr_Function_ushort = OpTypePointer Function %ushort
+%_ptr_Generic_ushort = OpTypePointer Generic %ushort
+ %ulong_2 = OpConstant %ulong 2
+ %bool = OpTypeBool
+ %false = OpConstantFalse %bool
+ %1 = OpFunction %void None %32
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %27 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ushort Function
+ %7 = OpVariable %_ptr_Function_ushort Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %24 = OpConvertUToPtr %_ptr_Generic_ushort %13
+ %12 = OpLoad %ushort %24
+ OpStore %6 %12
+ %15 = OpLoad %ulong %4
+ %22 = OpIAdd %ulong %15 %ulong_2
+ %25 = OpConvertUToPtr %_ptr_Generic_ushort %22
+ %14 = OpLoad %ushort %25
+ OpStore %7 %14
+ %17 = OpLoad %ushort %6
+ %18 = OpLoad %ushort %7
+ %16 = OpSelect %ushort %false %17 %18
+ OpStore %6 %16
+ %19 = OpLoad %ulong %5
+ %20 = OpLoad %ushort %6
+ %26 = OpConvertUToPtr %_ptr_Generic_ushort %19
+ OpStore %26 %20
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/selp_true.ptx b/ptx/src/test/spirv_run/selp_true.ptx
new file mode 100644
index 0000000..7abad81
--- /dev/null
+++ b/ptx/src/test/spirv_run/selp_true.ptx
@@ -0,0 +1,23 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry selp_true(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u16 temp1;
+ .reg .u16 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u16 temp1, [in_addr];
+ ld.u16 temp2, [in_addr + 2];
+ selp.u16 temp1, temp1, temp2, 1;
+ st.u16 [out_addr], temp1;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/selp_true.spvtxt b/ptx/src/test/spirv_run/selp_true.spvtxt
new file mode 100644
index 0000000..1880de1
--- /dev/null
+++ b/ptx/src/test/spirv_run/selp_true.spvtxt
@@ -0,0 +1,57 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %29 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "selp_true"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %32 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %ushort = OpTypeInt 16 0
+%_ptr_Function_ushort = OpTypePointer Function %ushort
+%_ptr_Generic_ushort = OpTypePointer Generic %ushort
+ %ulong_2 = OpConstant %ulong 2
+ %bool = OpTypeBool
+ %true = OpConstantTrue %bool
+ %1 = OpFunction %void None %32
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %27 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ushort Function
+ %7 = OpVariable %_ptr_Function_ushort Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %24 = OpConvertUToPtr %_ptr_Generic_ushort %13
+ %12 = OpLoad %ushort %24
+ OpStore %6 %12
+ %15 = OpLoad %ulong %4
+ %22 = OpIAdd %ulong %15 %ulong_2
+ %25 = OpConvertUToPtr %_ptr_Generic_ushort %22
+ %14 = OpLoad %ushort %25
+ OpStore %7 %14
+ %17 = OpLoad %ushort %6
+ %18 = OpLoad %ushort %7
+ %16 = OpSelect %ushort %true %17 %18
+ OpStore %6 %16
+ %19 = OpLoad %ulong %5
+ %20 = OpLoad %ushort %6
+ %26 = OpConvertUToPtr %_ptr_Generic_ushort %19
+ OpStore %26 %20
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/setp.ptx b/ptx/src/test/spirv_run/setp.ptx
new file mode 100644
index 0000000..8032505
--- /dev/null
+++ b/ptx/src/test/spirv_run/setp.ptx
@@ -0,0 +1,27 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry setp(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp;
+ .reg .u64 temp2;
+ .reg .u64 temp3;
+ .reg .pred pred;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u64 temp, [in_addr];
+ ld.u64 temp2, [in_addr + 8];
+ setp.lt.u64 pred, temp, temp2;
+ @pred mov.u64 temp3, 1;
+ @!pred mov.u64 temp3, 2;
+ st.u64 [out_addr], temp3;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/setp.spvtxt b/ptx/src/test/spirv_run/setp.spvtxt
new file mode 100644
index 0000000..ec94573
--- /dev/null
+++ b/ptx/src/test/spirv_run/setp.spvtxt
@@ -0,0 +1,73 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %40 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "setp"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %43 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %bool = OpTypeBool
+%_ptr_Function_bool = OpTypePointer Function %bool
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %ulong_8 = OpConstant %ulong 8
+ %ulong_1 = OpConstant %ulong 1
+ %ulong_2 = OpConstant %ulong 2
+ %1 = OpFunction %void None %43
+ %14 = OpFunctionParameter %ulong
+ %15 = OpFunctionParameter %ulong
+ %38 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ %8 = OpVariable %_ptr_Function_ulong Function
+ %9 = OpVariable %_ptr_Function_bool Function
+ OpStore %2 %14
+ OpStore %3 %15
+ %16 = OpLoad %ulong %2
+ OpStore %4 %16
+ %17 = OpLoad %ulong %3
+ OpStore %5 %17
+ %19 = OpLoad %ulong %4
+ %35 = OpConvertUToPtr %_ptr_Generic_ulong %19
+ %18 = OpLoad %ulong %35
+ OpStore %6 %18
+ %21 = OpLoad %ulong %4
+ %32 = OpIAdd %ulong %21 %ulong_8
+ %36 = OpConvertUToPtr %_ptr_Generic_ulong %32
+ %20 = OpLoad %ulong %36
+ OpStore %7 %20
+ %23 = OpLoad %ulong %6
+ %24 = OpLoad %ulong %7
+ %22 = OpULessThan %bool %23 %24
+ OpStore %9 %22
+ %25 = OpLoad %bool %9
+ OpBranchConditional %25 %10 %11
+ %10 = OpLabel
+ %26 = OpCopyObject %ulong %ulong_1
+ OpStore %8 %26
+ OpBranch %11
+ %11 = OpLabel
+ %27 = OpLoad %bool %9
+ OpBranchConditional %27 %13 %12
+ %12 = OpLabel
+ %28 = OpCopyObject %ulong %ulong_2
+ OpStore %8 %28
+ OpBranch %13
+ %13 = OpLabel
+ %29 = OpLoad %ulong %5
+ %30 = OpLoad %ulong %8
+ %37 = OpConvertUToPtr %_ptr_Generic_ulong %29
+ OpStore %37 %30
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/shared_ptr_32.ptx b/ptx/src/test/spirv_run/shared_ptr_32.ptx
new file mode 100644
index 0000000..0334aa0
--- /dev/null
+++ b/ptx/src/test/spirv_run/shared_ptr_32.ptx
@@ -0,0 +1,29 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+
+.visible .entry shared_ptr_32(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .shared .align 4 .b8 shared_mem1[128];
+
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u32 shared_addr;
+
+ .reg .u64 temp1;
+ .reg .u64 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+ mov.u32 shared_addr, shared_mem1;
+
+ ld.global.u64 temp1, [in_addr];
+ st.shared.u64 [shared_addr], temp1;
+ ld.shared.u64 temp2, [shared_addr+0];
+ st.global.u64 [out_addr], temp2;
+ ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/shared_ptr_32.spvtxt b/ptx/src/test/spirv_run/shared_ptr_32.spvtxt
new file mode 100644
index 0000000..98e2501
--- /dev/null
+++ b/ptx/src/test/spirv_run/shared_ptr_32.spvtxt
@@ -0,0 +1,66 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %32 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "shared_ptr_32" %4
+ OpDecorate %4 Alignment 4
+ %void = OpTypeVoid
+ %uint = OpTypeInt 32 0
+ %uchar = OpTypeInt 8 0
+ %uint_128 = OpConstant %uint 128
+%_arr_uchar_uint_128 = OpTypeArray %uchar %uint_128
+%_ptr_Workgroup__arr_uchar_uint_128 = OpTypePointer Workgroup %_arr_uchar_uint_128
+ %4 = OpVariable %_ptr_Workgroup__arr_uchar_uint_128 Workgroup
+ %ulong = OpTypeInt 64 0
+ %40 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong
+%_ptr_Workgroup_ulong = OpTypePointer Workgroup %ulong
+ %uint_0 = OpConstant %uint 0
+ %1 = OpFunction %void None %40
+ %10 = OpFunctionParameter %ulong
+ %11 = OpFunctionParameter %ulong
+ %30 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_uint Function
+ %8 = OpVariable %_ptr_Function_ulong Function
+ %9 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %10
+ OpStore %3 %11
+ %12 = OpLoad %ulong %2
+ OpStore %5 %12
+ %13 = OpLoad %ulong %3
+ OpStore %6 %13
+ %25 = OpConvertPtrToU %uint %4
+ %14 = OpCopyObject %uint %25
+ OpStore %7 %14
+ %16 = OpLoad %ulong %5
+ %26 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %16
+ %15 = OpLoad %ulong %26
+ OpStore %8 %15
+ %17 = OpLoad %uint %7
+ %18 = OpLoad %ulong %8
+ %27 = OpConvertUToPtr %_ptr_Workgroup_ulong %17
+ OpStore %27 %18
+ %20 = OpLoad %uint %7
+ %24 = OpIAdd %uint %20 %uint_0
+ %28 = OpConvertUToPtr %_ptr_Workgroup_ulong %24
+ %19 = OpLoad %ulong %28
+ OpStore %9 %19
+ %21 = OpLoad %ulong %6
+ %22 = OpLoad %ulong %9
+ %29 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %21
+ OpStore %29 %22
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/shared_ptr_take_address.ptx b/ptx/src/test/spirv_run/shared_ptr_take_address.ptx
new file mode 100644
index 0000000..e892993
--- /dev/null
+++ b/ptx/src/test/spirv_run/shared_ptr_take_address.ptx
@@ -0,0 +1,27 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.extern .shared .align 4 .b8 shared_mem[];
+
+.visible .entry shared_ptr_take_address(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 shared_addr;
+ .reg .u64 temp1;
+ .reg .u64 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+ mov.u64 shared_addr, shared_mem;
+
+ ld.global.u64 temp1, [in_addr];
+ st.shared.u64 [shared_addr], temp1;
+ ld.shared.u64 temp2, [shared_addr];
+ st.global.u64 [out_addr], temp2;
+ ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/shared_ptr_take_address.spvtxt b/ptx/src/test/spirv_run/shared_ptr_take_address.spvtxt
new file mode 100644
index 0000000..d77c2c8
--- /dev/null
+++ b/ptx/src/test/spirv_run/shared_ptr_take_address.spvtxt
@@ -0,0 +1,68 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %33 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %2 "shared_ptr_take_address" %1
+ OpDecorate %1 Alignment 4
+ %void = OpTypeVoid
+ %uchar = OpTypeInt 8 0
+%_ptr_Workgroup_uchar = OpTypePointer Workgroup %uchar
+%_ptr_Workgroup__ptr_Workgroup_uchar = OpTypePointer Workgroup %_ptr_Workgroup_uchar
+ %1 = OpVariable %_ptr_Workgroup__ptr_Workgroup_uchar Workgroup
+ %ulong = OpTypeInt 64 0
+ %39 = OpTypeFunction %void %ulong %ulong %_ptr_Workgroup_uchar
+%_ptr_Function__ptr_Workgroup_uchar = OpTypePointer Function %_ptr_Workgroup_uchar
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong
+%_ptr_Workgroup_ulong = OpTypePointer Workgroup %ulong
+ %2 = OpFunction %void None %39
+ %10 = OpFunctionParameter %ulong
+ %11 = OpFunctionParameter %ulong
+ %31 = OpFunctionParameter %_ptr_Workgroup_uchar
+ %40 = OpLabel
+ %32 = OpVariable %_ptr_Function__ptr_Workgroup_uchar Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ %8 = OpVariable %_ptr_Function_ulong Function
+ %9 = OpVariable %_ptr_Function_ulong Function
+ OpStore %32 %31
+ OpBranch %29
+ %29 = OpLabel
+ OpStore %3 %10
+ OpStore %4 %11
+ %12 = OpLoad %ulong %3
+ OpStore %5 %12
+ %13 = OpLoad %ulong %4
+ OpStore %6 %13
+ %15 = OpLoad %_ptr_Workgroup_uchar %32
+ %24 = OpConvertPtrToU %ulong %15
+ %14 = OpCopyObject %ulong %24
+ OpStore %7 %14
+ %17 = OpLoad %ulong %5
+ %25 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %17
+ %16 = OpLoad %ulong %25
+ OpStore %8 %16
+ %18 = OpLoad %ulong %7
+ %19 = OpLoad %ulong %8
+ %26 = OpConvertUToPtr %_ptr_Workgroup_ulong %18
+ OpStore %26 %19
+ %21 = OpLoad %ulong %7
+ %27 = OpConvertUToPtr %_ptr_Workgroup_ulong %21
+ %20 = OpLoad %ulong %27
+ OpStore %9 %20
+ %22 = OpLoad %ulong %6
+ %23 = OpLoad %ulong %9
+ %28 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %22
+ OpStore %28 %23
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/shared_variable.ptx b/ptx/src/test/spirv_run/shared_variable.ptx
new file mode 100644
index 0000000..4f7eff3
--- /dev/null
+++ b/ptx/src/test/spirv_run/shared_variable.ptx
@@ -0,0 +1,26 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+
+.visible .entry shared_variable(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .shared .align 4 .b8 shared_mem1[128];
+
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp1;
+ .reg .u64 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.global.u64 temp1, [in_addr];
+ st.shared.u64 [shared_mem1], temp1;
+ ld.shared.u64 temp2, [shared_mem1];
+ st.global.u64 [out_addr], temp2;
+ ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/shared_variable.spvtxt b/ptx/src/test/spirv_run/shared_variable.spvtxt
new file mode 100644
index 0000000..ffd6bd6
--- /dev/null
+++ b/ptx/src/test/spirv_run/shared_variable.spvtxt
@@ -0,0 +1,57 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %25 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "shared_variable" %4
+ OpDecorate %4 Alignment 4
+ %void = OpTypeVoid
+ %uint = OpTypeInt 32 0
+ %uchar = OpTypeInt 8 0
+ %uint_128 = OpConstant %uint 128
+%_arr_uchar_uint_128 = OpTypeArray %uchar %uint_128
+%_ptr_Workgroup__arr_uchar_uint_128 = OpTypePointer Workgroup %_arr_uchar_uint_128
+ %4 = OpVariable %_ptr_Workgroup__arr_uchar_uint_128 Workgroup
+ %ulong = OpTypeInt 64 0
+ %33 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong
+%_ptr_Workgroup_ulong = OpTypePointer Workgroup %ulong
+ %1 = OpFunction %void None %33
+ %9 = OpFunctionParameter %ulong
+ %10 = OpFunctionParameter %ulong
+ %23 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ %8 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %9
+ OpStore %3 %10
+ %11 = OpLoad %ulong %2
+ OpStore %5 %11
+ %12 = OpLoad %ulong %3
+ OpStore %6 %12
+ %14 = OpLoad %ulong %5
+ %19 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %14
+ %13 = OpLoad %ulong %19
+ OpStore %7 %13
+ %15 = OpLoad %ulong %7
+ %20 = OpBitcast %_ptr_Workgroup_ulong %4
+ OpStore %20 %15
+ %21 = OpBitcast %_ptr_Workgroup_ulong %4
+ %16 = OpLoad %ulong %21
+ OpStore %8 %16
+ %17 = OpLoad %ulong %6
+ %18 = OpLoad %ulong %8
+ %22 = OpConvertUToPtr %_ptr_CrossWorkgroup_ulong %17
+ OpStore %22 %18
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/shl.ptx b/ptx/src/test/spirv_run/shl.ptx
new file mode 100644
index 0000000..e888741
--- /dev/null
+++ b/ptx/src/test/spirv_run/shl.ptx
@@ -0,0 +1,22 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry shl(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp;
+ .reg .u64 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u64 temp, [in_addr];
+ shl.b64 temp2, temp, 2;
+ st.u64 [out_addr], temp2;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/shl.spvtxt b/ptx/src/test/spirv_run/shl.spvtxt
new file mode 100644
index 0000000..5841146
--- /dev/null
+++ b/ptx/src/test/spirv_run/shl.spvtxt
@@ -0,0 +1,51 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %25 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "shl"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %28 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %uint = OpTypeInt 32 0
+ %uint_2 = OpConstant %uint 2
+ %1 = OpFunction %void None %28
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %23 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %19 = OpConvertUToPtr %_ptr_Generic_ulong %13
+ %12 = OpLoad %ulong %19
+ OpStore %6 %12
+ %15 = OpLoad %ulong %6
+ %21 = OpCopyObject %ulong %15
+ %32 = OpUConvert %ulong %uint_2
+ %20 = OpShiftLeftLogical %ulong %21 %32
+ %14 = OpCopyObject %ulong %20
+ OpStore %7 %14
+ %16 = OpLoad %ulong %5
+ %17 = OpLoad %ulong %7
+ %22 = OpConvertUToPtr %_ptr_Generic_ulong %16
+ OpStore %22 %17
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/shl_link_hack.ptx b/ptx/src/test/spirv_run/shl_link_hack.ptx
new file mode 100644
index 0000000..a32555c
--- /dev/null
+++ b/ptx/src/test/spirv_run/shl_link_hack.ptx
@@ -0,0 +1,30 @@
+// HACK ALERT
+// This test is for testing workaround for a bug in IGC where linking fails
+// if there is shl/shr with different width of value and shift
+
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry shl_link_hack(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp;
+ .reg .u64 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ // Here only to trigger linking
+ .reg .u32 unused;
+ atom.inc.u32 unused, [out_addr], 2000000;
+
+ ld.u64 temp, [in_addr];
+ shl.b64 temp2, temp, 2;
+ st.u64 [out_addr], temp2;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/shl_link_hack.spvtxt b/ptx/src/test/spirv_run/shl_link_hack.spvtxt
new file mode 100644
index 0000000..8656049
--- /dev/null
+++ b/ptx/src/test/spirv_run/shl_link_hack.spvtxt
@@ -0,0 +1,65 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %34 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "shl_link_hack"
+ OpDecorate %29 LinkageAttributes "__zluda_ptx_impl__atom_relaxed_gpu_generic_inc" Import
+ %void = OpTypeVoid
+ %uint = OpTypeInt 32 0
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %38 = OpTypeFunction %uint %_ptr_Generic_uint %uint
+ %ulong = OpTypeInt 64 0
+ %40 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_2000000 = OpConstant %uint 2000000
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %uint_2 = OpConstant %uint 2
+ %29 = OpFunction %uint None %38
+ %31 = OpFunctionParameter %_ptr_Generic_uint
+ %32 = OpFunctionParameter %uint
+ OpFunctionEnd
+ %1 = OpFunction %void None %40
+ %9 = OpFunctionParameter %ulong
+ %10 = OpFunctionParameter %ulong
+ %28 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ %8 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %9
+ OpStore %3 %10
+ %11 = OpLoad %ulong %2
+ OpStore %4 %11
+ %12 = OpLoad %ulong %3
+ OpStore %5 %12
+ %14 = OpLoad %ulong %5
+ %23 = OpConvertUToPtr %_ptr_Generic_uint %14
+ %13 = OpFunctionCall %uint %29 %23 %uint_2000000
+ OpStore %8 %13
+ %16 = OpLoad %ulong %4
+ %24 = OpConvertUToPtr %_ptr_Generic_ulong %16
+ %15 = OpLoad %ulong %24
+ OpStore %6 %15
+ %18 = OpLoad %ulong %6
+ %26 = OpCopyObject %ulong %18
+ %44 = OpUConvert %ulong %uint_2
+ %25 = OpShiftLeftLogical %ulong %26 %44
+ %17 = OpCopyObject %ulong %25
+ OpStore %7 %17
+ %19 = OpLoad %ulong %5
+ %20 = OpLoad %ulong %7
+ %27 = OpConvertUToPtr %_ptr_Generic_ulong %19
+ OpStore %27 %20
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/shr.ptx b/ptx/src/test/spirv_run/shr.ptx
new file mode 100644
index 0000000..0a12fa7
--- /dev/null
+++ b/ptx/src/test/spirv_run/shr.ptx
@@ -0,0 +1,21 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry shr(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .s32 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.s32 temp, [in_addr];
+ shr.s32 temp, temp, 1;
+ st.s32 [out_addr], temp;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/shr.spvtxt b/ptx/src/test/spirv_run/shr.spvtxt
new file mode 100644
index 0000000..893dbf3
--- /dev/null
+++ b/ptx/src/test/spirv_run/shr.spvtxt
@@ -0,0 +1,48 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %22 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "shr"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %25 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %uint_1 = OpConstant %uint 1
+ %1 = OpFunction %void None %25
+ %7 = OpFunctionParameter %ulong
+ %8 = OpFunctionParameter %ulong
+ %20 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %7
+ OpStore %3 %8
+ %9 = OpLoad %ulong %2
+ OpStore %4 %9
+ %10 = OpLoad %ulong %3
+ OpStore %5 %10
+ %12 = OpLoad %ulong %4
+ %18 = OpConvertUToPtr %_ptr_Generic_uint %12
+ %11 = OpLoad %uint %18
+ OpStore %6 %11
+ %14 = OpLoad %uint %6
+ %13 = OpShiftRightArithmetic %uint %14 %uint_1
+ OpStore %6 %13
+ %15 = OpLoad %ulong %5
+ %16 = OpLoad %uint %6
+ %19 = OpConvertUToPtr %_ptr_Generic_uint %15
+ OpStore %19 %16
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/sin.ptx b/ptx/src/test/spirv_run/sin.ptx
new file mode 100644
index 0000000..fe94cac
--- /dev/null
+++ b/ptx/src/test/spirv_run/sin.ptx
@@ -0,0 +1,21 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry sin(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .f32 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.f32 temp, [in_addr];
+ sin.approx.f32 temp, temp;
+ st.f32 [out_addr], temp;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/sin.spvtxt b/ptx/src/test/spirv_run/sin.spvtxt
new file mode 100644
index 0000000..6656a43
--- /dev/null
+++ b/ptx/src/test/spirv_run/sin.spvtxt
@@ -0,0 +1,47 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %21 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "sin"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %24 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+%_ptr_Generic_float = OpTypePointer Generic %float
+ %1 = OpFunction %void None %24
+ %7 = OpFunctionParameter %ulong
+ %8 = OpFunctionParameter %ulong
+ %19 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_float Function
+ OpStore %2 %7
+ OpStore %3 %8
+ %9 = OpLoad %ulong %2
+ OpStore %4 %9
+ %10 = OpLoad %ulong %3
+ OpStore %5 %10
+ %12 = OpLoad %ulong %4
+ %17 = OpConvertUToPtr %_ptr_Generic_float %12
+ %11 = OpLoad %float %17
+ OpStore %6 %11
+ %14 = OpLoad %float %6
+ %13 = OpExtInst %float %21 sin %14
+ OpStore %6 %13
+ %15 = OpLoad %ulong %5
+ %16 = OpLoad %float %6
+ %18 = OpConvertUToPtr %_ptr_Generic_float %15
+ OpStore %18 %16
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/sqrt.ptx b/ptx/src/test/spirv_run/sqrt.ptx
new file mode 100644
index 0000000..8b42f34
--- /dev/null
+++ b/ptx/src/test/spirv_run/sqrt.ptx
@@ -0,0 +1,21 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry sqrt(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .f32 temp1;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.f32 temp1, [in_addr];
+ sqrt.approx.f32 temp1, temp1;
+ st.f32 [out_addr], temp1;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/sqrt.spvtxt b/ptx/src/test/spirv_run/sqrt.spvtxt
new file mode 100644
index 0000000..6d1cfd2
--- /dev/null
+++ b/ptx/src/test/spirv_run/sqrt.spvtxt
@@ -0,0 +1,47 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %21 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "sqrt"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %24 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+%_ptr_Generic_float = OpTypePointer Generic %float
+ %1 = OpFunction %void None %24
+ %7 = OpFunctionParameter %ulong
+ %8 = OpFunctionParameter %ulong
+ %19 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_float Function
+ OpStore %2 %7
+ OpStore %3 %8
+ %9 = OpLoad %ulong %2
+ OpStore %4 %9
+ %10 = OpLoad %ulong %3
+ OpStore %5 %10
+ %12 = OpLoad %ulong %4
+ %17 = OpConvertUToPtr %_ptr_Generic_float %12
+ %11 = OpLoad %float %17
+ OpStore %6 %11
+ %14 = OpLoad %float %6
+ %13 = OpExtInst %float %21 native_sqrt %14
+ OpStore %6 %13
+ %15 = OpLoad %ulong %5
+ %16 = OpLoad %float %6
+ %18 = OpConvertUToPtr %_ptr_Generic_float %15
+ OpStore %18 %16
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/stateful_ld_st_ntid.ptx b/ptx/src/test/spirv_run/stateful_ld_st_ntid.ptx
new file mode 100644
index 0000000..1fc37d1
--- /dev/null
+++ b/ptx/src/test/spirv_run/stateful_ld_st_ntid.ptx
@@ -0,0 +1,31 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry stateful_ld_st_ntid(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .b64 in_addr;
+ .reg .b64 out_addr;
+ .reg .u32 tid_32;
+ .reg .u64 tid_64;
+ .reg .u64 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ cvta.to.global.u64 in_addr, in_addr;
+ cvta.to.global.u64 out_addr, out_addr;
+
+ mov.u32 tid_32, %tid.x;
+ cvt.u64.u32 tid_64, tid_32;
+
+ add.u64 in_addr, in_addr, tid_64;
+ add.u64 out_addr, out_addr, tid_64;
+
+ ld.global.u64 temp, [in_addr];
+ st.global.u64 [out_addr], temp;
+ ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/stateful_ld_st_ntid.spvtxt b/ptx/src/test/spirv_run/stateful_ld_st_ntid.spvtxt
new file mode 100644
index 0000000..bad44f4
--- /dev/null
+++ b/ptx/src/test/spirv_run/stateful_ld_st_ntid.spvtxt
@@ -0,0 +1,91 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %49 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "stateful_ld_st_ntid" %gl_LocalInvocationID
+ OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %v3ulong = OpTypeVector %ulong 3
+%_ptr_Input_v3ulong = OpTypePointer Input %v3ulong
+%gl_LocalInvocationID = OpVariable %_ptr_Input_v3ulong Input
+ %uchar = OpTypeInt 8 0
+%_ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %uchar
+ %56 = OpTypeFunction %void %_ptr_CrossWorkgroup_uchar %_ptr_CrossWorkgroup_uchar
+%_ptr_Function__ptr_CrossWorkgroup_uchar = OpTypePointer Function %_ptr_CrossWorkgroup_uchar
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong
+ %1 = OpFunction %void None %56
+ %20 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar
+ %21 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar
+ %47 = OpLabel
+ %2 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %3 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %10 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %11 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ %8 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %20
+ OpStore %3 %21
+ %13 = OpBitcast %_ptr_Function_ulong %2
+ %43 = OpLoad %ulong %13
+ %12 = OpCopyObject %ulong %43
+ %22 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %12
+ OpStore %10 %22
+ %15 = OpBitcast %_ptr_Function_ulong %3
+ %44 = OpLoad %ulong %15
+ %14 = OpCopyObject %ulong %44
+ %23 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %14
+ OpStore %11 %23
+ %24 = OpLoad %_ptr_CrossWorkgroup_uchar %10
+ %17 = OpConvertPtrToU %ulong %24
+ %16 = OpCopyObject %ulong %17
+ %25 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %16
+ OpStore %10 %25
+ %26 = OpLoad %_ptr_CrossWorkgroup_uchar %11
+ %19 = OpConvertPtrToU %ulong %26
+ %18 = OpCopyObject %ulong %19
+ %27 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %18
+ OpStore %11 %27
+ %61 = OpLoad %v3ulong %gl_LocalInvocationID
+ %42 = OpCompositeExtract %ulong %61 0
+ %62 = OpBitcast %ulong %42
+ %29 = OpUConvert %uint %62
+ %28 = OpCopyObject %uint %29
+ OpStore %6 %28
+ %31 = OpLoad %uint %6
+ %63 = OpBitcast %uint %31
+ %30 = OpUConvert %ulong %63
+ OpStore %7 %30
+ %33 = OpLoad %_ptr_CrossWorkgroup_uchar %10
+ %34 = OpLoad %ulong %7
+ %64 = OpBitcast %_ptr_CrossWorkgroup_uchar %33
+ %65 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %64 %34
+ %32 = OpBitcast %_ptr_CrossWorkgroup_uchar %65
+ OpStore %10 %32
+ %36 = OpLoad %_ptr_CrossWorkgroup_uchar %11
+ %37 = OpLoad %ulong %7
+ %66 = OpBitcast %_ptr_CrossWorkgroup_uchar %36
+ %67 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %66 %37
+ %35 = OpBitcast %_ptr_CrossWorkgroup_uchar %67
+ OpStore %11 %35
+ %39 = OpLoad %_ptr_CrossWorkgroup_uchar %10
+ %45 = OpBitcast %_ptr_CrossWorkgroup_ulong %39
+ %38 = OpLoad %ulong %45
+ OpStore %8 %38
+ %40 = OpLoad %_ptr_CrossWorkgroup_uchar %11
+ %41 = OpLoad %ulong %8
+ %46 = OpBitcast %_ptr_CrossWorkgroup_ulong %40
+ OpStore %46 %41
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/stateful_ld_st_ntid_chain.ptx b/ptx/src/test/spirv_run/stateful_ld_st_ntid_chain.ptx
new file mode 100644
index 0000000..ef7645d
--- /dev/null
+++ b/ptx/src/test/spirv_run/stateful_ld_st_ntid_chain.ptx
@@ -0,0 +1,35 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry stateful_ld_st_ntid_chain(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .b64 in_addr1;
+ .reg .b64 in_addr2;
+ .reg .b64 in_addr3;
+ .reg .b64 out_addr1;
+ .reg .b64 out_addr2;
+ .reg .b64 out_addr3;
+ .reg .u32 tid_32;
+ .reg .u64 tid_64;
+ .reg .u64 temp;
+
+ ld.param.u64 in_addr1, [input];
+ ld.param.u64 out_addr1, [output];
+
+ cvta.to.global.u64 in_addr2, in_addr1;
+ cvta.to.global.u64 out_addr2, out_addr1;
+
+ mov.u32 tid_32, %tid.x;
+ cvt.u64.u32 tid_64, tid_32;
+
+ add.u64 in_addr3, in_addr2, tid_64;
+ add.u64 out_addr3, out_addr2, tid_64;
+
+ ld.global.u64 temp, [in_addr3];
+ st.global.u64 [out_addr3], temp;
+ ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/stateful_ld_st_ntid_chain.spvtxt b/ptx/src/test/spirv_run/stateful_ld_st_ntid_chain.spvtxt
new file mode 100644
index 0000000..cc99aa0
--- /dev/null
+++ b/ptx/src/test/spirv_run/stateful_ld_st_ntid_chain.spvtxt
@@ -0,0 +1,95 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %57 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "stateful_ld_st_ntid_chain" %gl_LocalInvocationID
+ OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %v3ulong = OpTypeVector %ulong 3
+%_ptr_Input_v3ulong = OpTypePointer Input %v3ulong
+%gl_LocalInvocationID = OpVariable %_ptr_Input_v3ulong Input
+ %uchar = OpTypeInt 8 0
+%_ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %uchar
+ %64 = OpTypeFunction %void %_ptr_CrossWorkgroup_uchar %_ptr_CrossWorkgroup_uchar
+%_ptr_Function__ptr_CrossWorkgroup_uchar = OpTypePointer Function %_ptr_CrossWorkgroup_uchar
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong
+ %1 = OpFunction %void None %64
+ %28 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar
+ %29 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar
+ %55 = OpLabel
+ %2 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %3 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %14 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %15 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %16 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %17 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %18 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %19 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %10 = OpVariable %_ptr_Function_uint Function
+ %11 = OpVariable %_ptr_Function_ulong Function
+ %12 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %28
+ OpStore %3 %29
+ %21 = OpBitcast %_ptr_Function_ulong %2
+ %51 = OpLoad %ulong %21
+ %20 = OpCopyObject %ulong %51
+ %30 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %20
+ OpStore %14 %30
+ %23 = OpBitcast %_ptr_Function_ulong %3
+ %52 = OpLoad %ulong %23
+ %22 = OpCopyObject %ulong %52
+ %31 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %22
+ OpStore %17 %31
+ %32 = OpLoad %_ptr_CrossWorkgroup_uchar %14
+ %25 = OpConvertPtrToU %ulong %32
+ %24 = OpCopyObject %ulong %25
+ %33 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %24
+ OpStore %15 %33
+ %34 = OpLoad %_ptr_CrossWorkgroup_uchar %17
+ %27 = OpConvertPtrToU %ulong %34
+ %26 = OpCopyObject %ulong %27
+ %35 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %26
+ OpStore %18 %35
+ %69 = OpLoad %v3ulong %gl_LocalInvocationID
+ %50 = OpCompositeExtract %ulong %69 0
+ %70 = OpBitcast %ulong %50
+ %37 = OpUConvert %uint %70
+ %36 = OpCopyObject %uint %37
+ OpStore %10 %36
+ %39 = OpLoad %uint %10
+ %71 = OpBitcast %uint %39
+ %38 = OpUConvert %ulong %71
+ OpStore %11 %38
+ %41 = OpLoad %_ptr_CrossWorkgroup_uchar %15
+ %42 = OpLoad %ulong %11
+ %72 = OpBitcast %_ptr_CrossWorkgroup_uchar %41
+ %73 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %72 %42
+ %40 = OpBitcast %_ptr_CrossWorkgroup_uchar %73
+ OpStore %16 %40
+ %44 = OpLoad %_ptr_CrossWorkgroup_uchar %18
+ %45 = OpLoad %ulong %11
+ %74 = OpBitcast %_ptr_CrossWorkgroup_uchar %44
+ %75 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %74 %45
+ %43 = OpBitcast %_ptr_CrossWorkgroup_uchar %75
+ OpStore %19 %43
+ %47 = OpLoad %_ptr_CrossWorkgroup_uchar %16
+ %53 = OpBitcast %_ptr_CrossWorkgroup_ulong %47
+ %46 = OpLoad %ulong %53
+ OpStore %12 %46
+ %48 = OpLoad %_ptr_CrossWorkgroup_uchar %19
+ %49 = OpLoad %ulong %12
+ %54 = OpBitcast %_ptr_CrossWorkgroup_ulong %48
+ OpStore %54 %49
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/stateful_ld_st_ntid_sub.ptx b/ptx/src/test/spirv_run/stateful_ld_st_ntid_sub.ptx
new file mode 100644
index 0000000..018918c
--- /dev/null
+++ b/ptx/src/test/spirv_run/stateful_ld_st_ntid_sub.ptx
@@ -0,0 +1,35 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry stateful_ld_st_ntid_sub(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .b64 in_addr1;
+ .reg .b64 in_addr2;
+ .reg .b64 in_addr3;
+ .reg .b64 out_addr1;
+ .reg .b64 out_addr2;
+ .reg .b64 out_addr3;
+ .reg .u32 tid_32;
+ .reg .u64 tid_64;
+ .reg .u64 temp;
+
+ ld.param.u64 in_addr1, [input];
+ ld.param.u64 out_addr1, [output];
+
+ cvta.to.global.u64 in_addr2, in_addr1;
+ cvta.to.global.u64 out_addr2, out_addr1;
+
+ mov.u32 tid_32, %tid.x;
+ cvt.u64.u32 tid_64, tid_32;
+
+ sub.s64 in_addr3, in_addr2, tid_64;
+ sub.s64 out_addr3, out_addr2, tid_64;
+
+ ld.global.u64 temp, [in_addr3+-0];
+ st.global.u64 [out_addr3+-0], temp;
+ ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/stateful_ld_st_ntid_sub.spvtxt b/ptx/src/test/spirv_run/stateful_ld_st_ntid_sub.spvtxt
new file mode 100644
index 0000000..32f2afb
--- /dev/null
+++ b/ptx/src/test/spirv_run/stateful_ld_st_ntid_sub.spvtxt
@@ -0,0 +1,107 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %65 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "stateful_ld_st_ntid_sub" %gl_LocalInvocationID
+ OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %v3ulong = OpTypeVector %ulong 3
+%_ptr_Input_v3ulong = OpTypePointer Input %v3ulong
+%gl_LocalInvocationID = OpVariable %_ptr_Input_v3ulong Input
+ %uchar = OpTypeInt 8 0
+%_ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %uchar
+ %72 = OpTypeFunction %void %_ptr_CrossWorkgroup_uchar %_ptr_CrossWorkgroup_uchar
+%_ptr_Function__ptr_CrossWorkgroup_uchar = OpTypePointer Function %_ptr_CrossWorkgroup_uchar
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %ulong_0 = OpConstant %ulong 0
+%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong
+ %ulong_0_0 = OpConstant %ulong 0
+ %1 = OpFunction %void None %72
+ %30 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar
+ %31 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar
+ %63 = OpLabel
+ %2 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %3 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %14 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %15 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %16 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %17 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %18 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %19 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %10 = OpVariable %_ptr_Function_uint Function
+ %11 = OpVariable %_ptr_Function_ulong Function
+ %12 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %30
+ OpStore %3 %31
+ %21 = OpBitcast %_ptr_Function_ulong %2
+ %57 = OpLoad %ulong %21
+ %20 = OpCopyObject %ulong %57
+ %32 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %20
+ OpStore %14 %32
+ %23 = OpBitcast %_ptr_Function_ulong %3
+ %58 = OpLoad %ulong %23
+ %22 = OpCopyObject %ulong %58
+ %33 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %22
+ OpStore %17 %33
+ %34 = OpLoad %_ptr_CrossWorkgroup_uchar %14
+ %25 = OpConvertPtrToU %ulong %34
+ %24 = OpCopyObject %ulong %25
+ %35 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %24
+ OpStore %15 %35
+ %36 = OpLoad %_ptr_CrossWorkgroup_uchar %17
+ %27 = OpConvertPtrToU %ulong %36
+ %26 = OpCopyObject %ulong %27
+ %37 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %26
+ OpStore %18 %37
+ %77 = OpLoad %v3ulong %gl_LocalInvocationID
+ %52 = OpCompositeExtract %ulong %77 0
+ %78 = OpBitcast %ulong %52
+ %39 = OpUConvert %uint %78
+ %38 = OpCopyObject %uint %39
+ OpStore %10 %38
+ %41 = OpLoad %uint %10
+ %79 = OpBitcast %uint %41
+ %40 = OpUConvert %ulong %79
+ OpStore %11 %40
+ %42 = OpLoad %ulong %11
+ %59 = OpCopyObject %ulong %42
+ %28 = OpSNegate %ulong %59
+ %44 = OpLoad %_ptr_CrossWorkgroup_uchar %15
+ %80 = OpBitcast %_ptr_CrossWorkgroup_uchar %44
+ %81 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %80 %28
+ %43 = OpBitcast %_ptr_CrossWorkgroup_uchar %81
+ OpStore %16 %43
+ %45 = OpLoad %ulong %11
+ %60 = OpCopyObject %ulong %45
+ %29 = OpSNegate %ulong %60
+ %47 = OpLoad %_ptr_CrossWorkgroup_uchar %18
+ %82 = OpBitcast %_ptr_CrossWorkgroup_uchar %47
+ %83 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %82 %29
+ %46 = OpBitcast %_ptr_CrossWorkgroup_uchar %83
+ OpStore %19 %46
+ %49 = OpLoad %_ptr_CrossWorkgroup_uchar %16
+ %61 = OpBitcast %_ptr_CrossWorkgroup_ulong %49
+ %85 = OpBitcast %_ptr_CrossWorkgroup_uchar %61
+ %86 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %85 %ulong_0
+ %54 = OpBitcast %_ptr_CrossWorkgroup_ulong %86
+ %48 = OpLoad %ulong %54
+ OpStore %12 %48
+ %50 = OpLoad %_ptr_CrossWorkgroup_uchar %19
+ %51 = OpLoad %ulong %12
+ %62 = OpBitcast %_ptr_CrossWorkgroup_ulong %50
+ %87 = OpBitcast %_ptr_CrossWorkgroup_uchar %62
+ %88 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uchar %87 %ulong_0_0
+ %56 = OpBitcast %_ptr_CrossWorkgroup_ulong %88
+ OpStore %56 %51
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/stateful_ld_st_simple.ptx b/ptx/src/test/spirv_run/stateful_ld_st_simple.ptx
new file mode 100644
index 0000000..5650ada
--- /dev/null
+++ b/ptx/src/test/spirv_run/stateful_ld_st_simple.ptx
@@ -0,0 +1,25 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry stateful_ld_st_simple(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 in_addr2;
+ .reg .u64 out_addr2;
+ .reg .u64 temp;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ cvta.to.global.u64 in_addr2, in_addr;
+ cvta.to.global.u64 out_addr2, out_addr;
+
+ ld.global.u64 temp, [in_addr2];
+ st.global.u64 [out_addr2], temp;
+ ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/stateful_ld_st_simple.spvtxt b/ptx/src/test/spirv_run/stateful_ld_st_simple.spvtxt
new file mode 100644
index 0000000..cfd87eb
--- /dev/null
+++ b/ptx/src/test/spirv_run/stateful_ld_st_simple.spvtxt
@@ -0,0 +1,65 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %41 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "stateful_ld_st_simple"
+ %void = OpTypeVoid
+ %uchar = OpTypeInt 8 0
+%_ptr_CrossWorkgroup_uchar = OpTypePointer CrossWorkgroup %uchar
+ %45 = OpTypeFunction %void %_ptr_CrossWorkgroup_uchar %_ptr_CrossWorkgroup_uchar
+%_ptr_Function__ptr_CrossWorkgroup_uchar = OpTypePointer Function %_ptr_CrossWorkgroup_uchar
+ %ulong = OpTypeInt 64 0
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_CrossWorkgroup_ulong = OpTypePointer CrossWorkgroup %ulong
+ %1 = OpFunction %void None %45
+ %21 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar
+ %22 = OpFunctionParameter %_ptr_CrossWorkgroup_uchar
+ %39 = OpLabel
+ %2 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %3 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %9 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %10 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %11 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %12 = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uchar Function
+ %8 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %21
+ OpStore %3 %22
+ %14 = OpBitcast %_ptr_Function_ulong %2
+ %13 = OpLoad %ulong %14
+ %23 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %13
+ OpStore %9 %23
+ %16 = OpBitcast %_ptr_Function_ulong %3
+ %15 = OpLoad %ulong %16
+ %24 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %15
+ OpStore %10 %24
+ %25 = OpLoad %_ptr_CrossWorkgroup_uchar %9
+ %18 = OpConvertPtrToU %ulong %25
+ %34 = OpCopyObject %ulong %18
+ %33 = OpCopyObject %ulong %34
+ %17 = OpCopyObject %ulong %33
+ %26 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %17
+ OpStore %11 %26
+ %27 = OpLoad %_ptr_CrossWorkgroup_uchar %10
+ %20 = OpConvertPtrToU %ulong %27
+ %36 = OpCopyObject %ulong %20
+ %35 = OpCopyObject %ulong %36
+ %19 = OpCopyObject %ulong %35
+ %28 = OpConvertUToPtr %_ptr_CrossWorkgroup_uchar %19
+ OpStore %12 %28
+ %30 = OpLoad %_ptr_CrossWorkgroup_uchar %11
+ %37 = OpBitcast %_ptr_CrossWorkgroup_ulong %30
+ %29 = OpLoad %ulong %37
+ OpStore %8 %29
+ %31 = OpLoad %_ptr_CrossWorkgroup_uchar %12
+ %32 = OpLoad %ulong %8
+ %38 = OpBitcast %_ptr_CrossWorkgroup_ulong %31
+ OpStore %38 %32
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/sub.ptx b/ptx/src/test/spirv_run/sub.ptx
new file mode 100644
index 0000000..6cce9dc
--- /dev/null
+++ b/ptx/src/test/spirv_run/sub.ptx
@@ -0,0 +1,22 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry sub(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u64 temp;
+ .reg .u64 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.u64 temp, [in_addr];
+ sub.u64 temp2, temp, 1;
+ st.u64 [out_addr], temp2;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/sub.spvtxt b/ptx/src/test/spirv_run/sub.spvtxt
new file mode 100644
index 0000000..88017ae
--- /dev/null
+++ b/ptx/src/test/spirv_run/sub.spvtxt
@@ -0,0 +1,47 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %23 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "sub"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %26 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Generic_ulong = OpTypePointer Generic %ulong
+ %ulong_1 = OpConstant %ulong 1
+ %1 = OpFunction %void None %26
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %21 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ulong Function
+ %7 = OpVariable %_ptr_Function_ulong Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %19 = OpConvertUToPtr %_ptr_Generic_ulong %13
+ %12 = OpLoad %ulong %19
+ OpStore %6 %12
+ %15 = OpLoad %ulong %6
+ %14 = OpISub %ulong %15 %ulong_1
+ OpStore %7 %14
+ %16 = OpLoad %ulong %5
+ %17 = OpLoad %ulong %7
+ %20 = OpConvertUToPtr %_ptr_Generic_ulong %16
+ OpStore %20 %17
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/vector.ptx b/ptx/src/test/spirv_run/vector.ptx
new file mode 100644
index 0000000..90b8ad3
--- /dev/null
+++ b/ptx/src/test/spirv_run/vector.ptx
@@ -0,0 +1,45 @@
+// Excersise as many features of vector types as possible
+
+.version 6.5
+.target sm_60
+.address_size 64
+
+.func (.reg .v2 .u32 output) impl(
+ .reg .v2 .u32 input
+)
+{
+ .reg .v2 .u32 temp_v;
+ .reg .u32 temp1;
+ .reg .u32 temp2;
+
+ mov.u32 temp1, input.x;
+ mov.u32 temp2, input.y;
+ add.u32 temp2, temp1, temp2;
+ mov.u32 temp_v.x, temp2;
+ mov.u32 temp_v.y, temp2;
+ mov.u32 temp_v.x, temp_v.y;
+ mov.v2.u32 output, temp_v;
+ ret;
+}
+
+.visible .entry vector(
+ .param .u64 input_p,
+ .param .u64 output_p
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .v2 .u32 temp;
+ .reg .u32 temp1;
+ .reg .u32 temp2;
+ .reg .b64 packed;
+
+ ld.param.u64 in_addr, [input_p];
+ ld.param.u64 out_addr, [output_p];
+
+ ld.v2.u32 temp, [in_addr];
+ call (temp), impl, (temp);
+ mov.b64 packed, temp;
+ st.v2.u32 [out_addr], temp;
+ ret;
+} \ No newline at end of file
diff --git a/ptx/src/test/spirv_run/vector.spvtxt b/ptx/src/test/spirv_run/vector.spvtxt
new file mode 100644
index 0000000..a77ab7d
--- /dev/null
+++ b/ptx/src/test/spirv_run/vector.spvtxt
@@ -0,0 +1,99 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %51 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %25 "vector"
+ %void = OpTypeVoid
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+ %55 = OpTypeFunction %v2uint %v2uint
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %ulong = OpTypeInt 64 0
+ %67 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%_ptr_Generic_v2uint = OpTypePointer Generic %v2uint
+ %1 = OpFunction %v2uint None %55
+ %7 = OpFunctionParameter %v2uint
+ %24 = OpLabel
+ %2 = OpVariable %_ptr_Function_v2uint Function
+ %3 = OpVariable %_ptr_Function_v2uint Function
+ %4 = OpVariable %_ptr_Function_v2uint Function
+ %5 = OpVariable %_ptr_Function_uint Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ OpStore %3 %7
+ %59 = OpInBoundsAccessChain %_ptr_Function_uint %3 %uint_0
+ %9 = OpLoad %uint %59
+ %8 = OpCopyObject %uint %9
+ OpStore %5 %8
+ %61 = OpInBoundsAccessChain %_ptr_Function_uint %3 %uint_1
+ %11 = OpLoad %uint %61
+ %10 = OpCopyObject %uint %11
+ OpStore %6 %10
+ %13 = OpLoad %uint %5
+ %14 = OpLoad %uint %6
+ %12 = OpIAdd %uint %13 %14
+ OpStore %6 %12
+ %16 = OpLoad %uint %6
+ %15 = OpCopyObject %uint %16
+ %62 = OpInBoundsAccessChain %_ptr_Function_uint %4 %uint_0
+ OpStore %62 %15
+ %18 = OpLoad %uint %6
+ %17 = OpCopyObject %uint %18
+ %63 = OpInBoundsAccessChain %_ptr_Function_uint %4 %uint_1
+ OpStore %63 %17
+ %64 = OpInBoundsAccessChain %_ptr_Function_uint %4 %uint_1
+ %20 = OpLoad %uint %64
+ %19 = OpCopyObject %uint %20
+ %65 = OpInBoundsAccessChain %_ptr_Function_uint %4 %uint_0
+ OpStore %65 %19
+ %22 = OpLoad %v2uint %4
+ %21 = OpCopyObject %v2uint %22
+ OpStore %2 %21
+ %23 = OpLoad %v2uint %2
+ OpReturnValue %23
+ OpFunctionEnd
+ %25 = OpFunction %void None %67
+ %34 = OpFunctionParameter %ulong
+ %35 = OpFunctionParameter %ulong
+ %49 = OpLabel
+ %26 = OpVariable %_ptr_Function_ulong Function
+ %27 = OpVariable %_ptr_Function_ulong Function
+ %28 = OpVariable %_ptr_Function_ulong Function
+ %29 = OpVariable %_ptr_Function_ulong Function
+ %30 = OpVariable %_ptr_Function_v2uint Function
+ %31 = OpVariable %_ptr_Function_uint Function
+ %32 = OpVariable %_ptr_Function_uint Function
+ %33 = OpVariable %_ptr_Function_ulong Function
+ OpStore %26 %34
+ OpStore %27 %35
+ %36 = OpLoad %ulong %26
+ OpStore %28 %36
+ %37 = OpLoad %ulong %27
+ OpStore %29 %37
+ %39 = OpLoad %ulong %28
+ %46 = OpConvertUToPtr %_ptr_Generic_v2uint %39
+ %38 = OpLoad %v2uint %46
+ OpStore %30 %38
+ %41 = OpLoad %v2uint %30
+ %40 = OpFunctionCall %v2uint %1 %41
+ OpStore %30 %40
+ %43 = OpLoad %v2uint %30
+ %47 = OpBitcast %ulong %43
+ %42 = OpCopyObject %ulong %47
+ OpStore %33 %42
+ %44 = OpLoad %ulong %29
+ %45 = OpLoad %v2uint %30
+ %48 = OpConvertUToPtr %_ptr_Generic_v2uint %44
+ OpStore %48 %45
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/vector_extract.ptx b/ptx/src/test/spirv_run/vector_extract.ptx
new file mode 100644
index 0000000..111f7c0
--- /dev/null
+++ b/ptx/src/test/spirv_run/vector_extract.ptx
@@ -0,0 +1,27 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry vector_extract(
+ .param .u64 input_p,
+ .param .u64 output_p
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .u16 temp1;
+ .reg .u16 temp2;
+ .reg .u16 temp3;
+ .reg .u16 temp4;
+ .reg .v4.u16 foo;
+
+ ld.param.u64 in_addr, [input_p];
+ ld.param.u64 out_addr, [output_p];
+
+ ld.global.v4.u8 {temp1, temp2, temp3, temp4}, [in_addr];
+ mov.v4.u16 foo, {temp2, temp3, temp4, temp1};
+ mov.v4.u16 {temp3, temp4, temp1, temp2}, foo;
+ mov.v4.u16 {temp4, temp1, temp2, temp3}, {temp3, temp4, temp1, temp2};
+ st.global.v4.u8 [out_addr], {temp1, temp2, temp3, temp4};
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/vector_extract.spvtxt b/ptx/src/test/spirv_run/vector_extract.spvtxt
new file mode 100644
index 0000000..2037dec
--- /dev/null
+++ b/ptx/src/test/spirv_run/vector_extract.spvtxt
@@ -0,0 +1,125 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %61 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "vector_extract"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %64 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %ushort = OpTypeInt 16 0
+%_ptr_Function_ushort = OpTypePointer Function %ushort
+ %v4ushort = OpTypeVector %ushort 4
+%_ptr_Function_v4ushort = OpTypePointer Function %v4ushort
+ %uchar = OpTypeInt 8 0
+ %v4uchar = OpTypeVector %uchar 4
+%_ptr_CrossWorkgroup_v4uchar = OpTypePointer CrossWorkgroup %v4uchar
+ %1 = OpFunction %void None %64
+ %17 = OpFunctionParameter %ulong
+ %18 = OpFunctionParameter %ulong
+ %59 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_ushort Function
+ %7 = OpVariable %_ptr_Function_ushort Function
+ %8 = OpVariable %_ptr_Function_ushort Function
+ %9 = OpVariable %_ptr_Function_ushort Function
+ %10 = OpVariable %_ptr_Function_v4ushort Function
+ OpStore %2 %17
+ OpStore %3 %18
+ %19 = OpLoad %ulong %2
+ OpStore %4 %19
+ %20 = OpLoad %ulong %3
+ OpStore %5 %20
+ %21 = OpLoad %ulong %4
+ %49 = OpConvertUToPtr %_ptr_CrossWorkgroup_v4uchar %21
+ %11 = OpLoad %v4uchar %49
+ %50 = OpCompositeExtract %uchar %11 0
+ %51 = OpCompositeExtract %uchar %11 1
+ %52 = OpCompositeExtract %uchar %11 2
+ %53 = OpCompositeExtract %uchar %11 3
+ %73 = OpBitcast %uchar %50
+ %22 = OpUConvert %ushort %73
+ %74 = OpBitcast %uchar %51
+ %23 = OpUConvert %ushort %74
+ %75 = OpBitcast %uchar %52
+ %24 = OpUConvert %ushort %75
+ %76 = OpBitcast %uchar %53
+ %25 = OpUConvert %ushort %76
+ OpStore %6 %22
+ OpStore %7 %23
+ OpStore %8 %24
+ OpStore %9 %25
+ %26 = OpLoad %ushort %7
+ %27 = OpLoad %ushort %8
+ %28 = OpLoad %ushort %9
+ %29 = OpLoad %ushort %6
+ %77 = OpUndef %v4ushort
+ %78 = OpCompositeInsert %v4ushort %26 %77 0
+ %79 = OpCompositeInsert %v4ushort %27 %78 1
+ %80 = OpCompositeInsert %v4ushort %28 %79 2
+ %81 = OpCompositeInsert %v4ushort %29 %80 3
+ %12 = OpCopyObject %v4ushort %81
+ %30 = OpCopyObject %v4ushort %12
+ OpStore %10 %30
+ %31 = OpLoad %v4ushort %10
+ %13 = OpCopyObject %v4ushort %31
+ %32 = OpCompositeExtract %ushort %13 0
+ %33 = OpCompositeExtract %ushort %13 1
+ %34 = OpCompositeExtract %ushort %13 2
+ %35 = OpCompositeExtract %ushort %13 3
+ OpStore %8 %32
+ OpStore %9 %33
+ OpStore %6 %34
+ OpStore %7 %35
+ %36 = OpLoad %ushort %8
+ %37 = OpLoad %ushort %9
+ %38 = OpLoad %ushort %6
+ %39 = OpLoad %ushort %7
+ %82 = OpUndef %v4ushort
+ %83 = OpCompositeInsert %v4ushort %36 %82 0
+ %84 = OpCompositeInsert %v4ushort %37 %83 1
+ %85 = OpCompositeInsert %v4ushort %38 %84 2
+ %86 = OpCompositeInsert %v4ushort %39 %85 3
+ %15 = OpCopyObject %v4ushort %86
+ %14 = OpCopyObject %v4ushort %15
+ %40 = OpCompositeExtract %ushort %14 0
+ %41 = OpCompositeExtract %ushort %14 1
+ %42 = OpCompositeExtract %ushort %14 2
+ %43 = OpCompositeExtract %ushort %14 3
+ OpStore %9 %40
+ OpStore %6 %41
+ OpStore %7 %42
+ OpStore %8 %43
+ %44 = OpLoad %ushort %6
+ %45 = OpLoad %ushort %7
+ %46 = OpLoad %ushort %8
+ %47 = OpLoad %ushort %9
+ %87 = OpBitcast %ushort %44
+ %54 = OpUConvert %uchar %87
+ %88 = OpBitcast %ushort %45
+ %55 = OpUConvert %uchar %88
+ %89 = OpBitcast %ushort %46
+ %56 = OpUConvert %uchar %89
+ %90 = OpBitcast %ushort %47
+ %57 = OpUConvert %uchar %90
+ %91 = OpUndef %v4uchar
+ %92 = OpCompositeInsert %v4uchar %54 %91 0
+ %93 = OpCompositeInsert %v4uchar %55 %92 1
+ %94 = OpCompositeInsert %v4uchar %56 %93 2
+ %95 = OpCompositeInsert %v4uchar %57 %94 3
+ %16 = OpCopyObject %v4uchar %95
+ %48 = OpLoad %ulong %5
+ %58 = OpConvertUToPtr %_ptr_CrossWorkgroup_v4uchar %48
+ OpStore %58 %16
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/spirv_run/xor.ptx b/ptx/src/test/spirv_run/xor.ptx
new file mode 100644
index 0000000..a28b321
--- /dev/null
+++ b/ptx/src/test/spirv_run/xor.ptx
@@ -0,0 +1,23 @@
+.version 6.5
+.target sm_30
+.address_size 64
+
+.visible .entry xor(
+ .param .u64 input,
+ .param .u64 output
+)
+{
+ .reg .u64 in_addr;
+ .reg .u64 out_addr;
+ .reg .b32 temp1;
+ .reg .b32 temp2;
+
+ ld.param.u64 in_addr, [input];
+ ld.param.u64 out_addr, [output];
+
+ ld.b32 temp1, [in_addr];
+ ld.b32 temp2, [in_addr+4];
+ xor.b32 temp1, temp1, temp2;
+ st.b32 [out_addr], temp1;
+ ret;
+}
diff --git a/ptx/src/test/spirv_run/xor.spvtxt b/ptx/src/test/spirv_run/xor.spvtxt
new file mode 100644
index 0000000..ee09898
--- /dev/null
+++ b/ptx/src/test/spirv_run/xor.spvtxt
@@ -0,0 +1,55 @@
+ OpCapability GenericPointer
+ OpCapability Linkage
+ OpCapability Addresses
+ OpCapability Kernel
+ OpCapability Int8
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Float16
+ OpCapability Float64
+ %28 = OpExtInstImport "OpenCL.std"
+ OpMemoryModel Physical64 OpenCL
+ OpEntryPoint Kernel %1 "xor"
+ %void = OpTypeVoid
+ %ulong = OpTypeInt 64 0
+ %31 = OpTypeFunction %void %ulong %ulong
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+ %uint = OpTypeInt 32 0
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Generic_uint = OpTypePointer Generic %uint
+ %ulong_4 = OpConstant %ulong 4
+ %1 = OpFunction %void None %31
+ %8 = OpFunctionParameter %ulong
+ %9 = OpFunctionParameter %ulong
+ %26 = OpLabel
+ %2 = OpVariable %_ptr_Function_ulong Function
+ %3 = OpVariable %_ptr_Function_ulong Function
+ %4 = OpVariable %_ptr_Function_ulong Function
+ %5 = OpVariable %_ptr_Function_ulong Function
+ %6 = OpVariable %_ptr_Function_uint Function
+ %7 = OpVariable %_ptr_Function_uint Function
+ OpStore %2 %8
+ OpStore %3 %9
+ %10 = OpLoad %ulong %2
+ OpStore %4 %10
+ %11 = OpLoad %ulong %3
+ OpStore %5 %11
+ %13 = OpLoad %ulong %4
+ %23 = OpConvertUToPtr %_ptr_Generic_uint %13
+ %12 = OpLoad %uint %23
+ OpStore %6 %12
+ %15 = OpLoad %ulong %4
+ %22 = OpIAdd %ulong %15 %ulong_4
+ %24 = OpConvertUToPtr %_ptr_Generic_uint %22
+ %14 = OpLoad %uint %24
+ OpStore %7 %14
+ %17 = OpLoad %uint %6
+ %18 = OpLoad %uint %7
+ %16 = OpBitwiseXor %uint %17 %18
+ OpStore %6 %16
+ %19 = OpLoad %ulong %5
+ %20 = OpLoad %uint %6
+ %25 = OpConvertUToPtr %_ptr_Generic_uint %19
+ OpStore %25 %20
+ OpReturn
+ OpFunctionEnd
diff --git a/ptx/src/test/vectorAdd_11.ptx b/ptx/src/test/vectorAdd_11.ptx
new file mode 100644
index 0000000..ba0381e
--- /dev/null
+++ b/ptx/src/test/vectorAdd_11.ptx
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+.version 7.0
+.target sm_80
+.address_size 64
+
+
+
+.visible .entry _Z9vectorAddPKfS0_Pfi(
+.param .u64 _Z9vectorAddPKfS0_Pfi_param_0,
+.param .u64 _Z9vectorAddPKfS0_Pfi_param_1,
+.param .u64 _Z9vectorAddPKfS0_Pfi_param_2,
+.param .u32 _Z9vectorAddPKfS0_Pfi_param_3
+)
+{
+.reg .pred %p<2>;
+.reg .f32 %f<4>;
+.reg .b32 %r<6>;
+.reg .b64 %rd<11>;
+
+
+ld.param.u64 %rd1, [_Z9vectorAddPKfS0_Pfi_param_0];
+ld.param.u64 %rd2, [_Z9vectorAddPKfS0_Pfi_param_1];
+ld.param.u64 %rd3, [_Z9vectorAddPKfS0_Pfi_param_2];
+ld.param.u32 %r2, [_Z9vectorAddPKfS0_Pfi_param_3];
+mov.u32 %r3, %ntid.x;
+mov.u32 %r4, %ctaid.x;
+mov.u32 %r5, %tid.x;
+mad.lo.s32 %r1, %r4, %r3, %r5;
+setp.ge.s32 %p1, %r1, %r2;
+@%p1 bra BB0_2;
+
+cvta.to.global.u64 %rd4, %rd1;
+mul.wide.s32 %rd5, %r1, 4;
+add.s64 %rd6, %rd4, %rd5;
+cvta.to.global.u64 %rd7, %rd2;
+add.s64 %rd8, %rd7, %rd5;
+ld.global.f32 %f1, [%rd8];
+ld.global.f32 %f2, [%rd6];
+add.f32 %f3, %f2, %f1;
+cvta.to.global.u64 %rd9, %rd3;
+add.s64 %rd10, %rd9, %rd5;
+st.global.f32 [%rd10], %f3;
+
+BB0_2:
+ret;
+}
+
+
diff --git a/ptx/src/test/vectorAdd_kernel64.ptx b/ptx/src/test/vectorAdd_kernel64.ptx
new file mode 100644
index 0000000..100cd93
--- /dev/null
+++ b/ptx/src/test/vectorAdd_kernel64.ptx
@@ -0,0 +1,592 @@
+//
+// Generated by NVIDIA NVVM Compiler
+//
+// Compiler Build ID: CL-27506705
+// Cuda compilation tools, release 10.2, V10.2.89
+// Based on LLVM 3.4svn
+//
+
+.version 6.5
+.target sm_30, debug
+.address_size 64
+
+ // .globl VecAdd_kernel
+
+.visible .entry VecAdd_kernel(
+ .param .u64 VecAdd_kernel_param_0,
+ .param .u64 VecAdd_kernel_param_1,
+ .param .u64 VecAdd_kernel_param_2,
+ .param .u32 VecAdd_kernel_param_3
+)
+{
+ .reg .pred %p<3>;
+ .reg .f32 %f<4>;
+ .reg .b32 %r<7>;
+ .reg .b64 %rd<13>;
+
+
+ .loc 1 21 1
+func_begin0:
+ .loc 1 0 0
+
+ .loc 1 21 1
+
+ ld.param.u64 %rd1, [VecAdd_kernel_param_0];
+ ld.param.u64 %rd2, [VecAdd_kernel_param_1];
+ ld.param.u64 %rd3, [VecAdd_kernel_param_2];
+ ld.param.u32 %r2, [VecAdd_kernel_param_3];
+func_exec_begin0:
+ .loc 1 23 11
+tmp0:
+ mov.u32 %r3, %ntid.x;
+ mov.u32 %r4, %ctaid.x;
+ mul.lo.s32 %r5, %r3, %r4;
+ mov.u32 %r6, %tid.x;
+ add.s32 %r1, %r5, %r6;
+tmp1:
+ .loc 1 25 5
+ setp.lt.s32 %p1, %r1, %r2;
+ not.pred %p2, %p1;
+ @%p2 bra BB0_2;
+ bra.uni BB0_1;
+
+BB0_1:
+ .loc 1 26 9
+tmp2:
+ cvt.s64.s32 %rd4, %r1;
+ shl.b64 %rd5, %rd4, 2;
+ add.s64 %rd6, %rd1, %rd5;
+ ld.f32 %f1, [%rd6];
+ cvt.s64.s32 %rd7, %r1;
+ shl.b64 %rd8, %rd7, 2;
+ add.s64 %rd9, %rd2, %rd8;
+ ld.f32 %f2, [%rd9];
+ add.f32 %f3, %f1, %f2;
+ cvt.s64.s32 %rd10, %r1;
+ shl.b64 %rd11, %rd10, 2;
+ add.s64 %rd12, %rd3, %rd11;
+ st.f32 [%rd12], %f3;
+tmp3:
+
+BB0_2:
+ .loc 1 27 1
+ ret;
+tmp4:
+func_end0:
+}
+
+ .file 1 "/home/vosen/cuda-samples/0_Simple/vectorAddMMAP/vectorAdd_kernel.cu", 1581801938, 860
+
+.section .debug_info {
+ .b32 314
+ .b8 2
+ .b8 0
+ .b32 .debug_abbrev
+ .b8 8
+ .b8 1
+
+ .b8 108
+ .b8 103
+ .b8 101
+ .b8 110
+ .b8 102
+ .b8 101
+ .b8 58
+ .b8 32
+ .b8 69
+ .b8 68
+ .b8 71
+ .b8 32
+ .b8 53
+ .b8 46
+ .b8 48
+
+ .b8 0
+ .b8 4
+ .b8 118
+ .b8 101
+ .b8 99
+ .b8 116
+ .b8 111
+ .b8 114
+ .b8 65
+ .b8 100
+ .b8 100
+ .b8 95
+ .b8 107
+ .b8 101
+ .b8 114
+ .b8 110
+ .b8 101
+ .b8 108
+ .b8 46
+ .b8 99
+ .b8 117
+
+ .b8 0
+ .b64 0
+ .b32 .debug_line
+ .b8 47
+ .b8 104
+ .b8 111
+ .b8 109
+ .b8 101
+ .b8 47
+ .b8 118
+ .b8 111
+ .b8 115
+ .b8 101
+ .b8 110
+ .b8 47
+ .b8 99
+ .b8 117
+ .b8 100
+ .b8 97
+ .b8 45
+ .b8 115
+ .b8 97
+ .b8 109
+ .b8 112
+ .b8 108
+ .b8 101
+ .b8 115
+ .b8 47
+ .b8 48
+ .b8 95
+ .b8 83
+ .b8 105
+ .b8 109
+ .b8 112
+ .b8 108
+ .b8 101
+ .b8 47
+ .b8 118
+ .b8 101
+ .b8 99
+ .b8 116
+ .b8 111
+ .b8 114
+ .b8 65
+ .b8 100
+ .b8 100
+ .b8 77
+ .b8 77
+ .b8 65
+ .b8 80
+
+ .b8 0
+ .b8 2
+
+ .b8 86
+ .b8 101
+ .b8 99
+ .b8 65
+ .b8 100
+ .b8 100
+ .b8 95
+ .b8 107
+ .b8 101
+ .b8 114
+ .b8 110
+ .b8 101
+ .b8 108
+
+ .b8 0
+ .b8 86
+ .b8 101
+ .b8 99
+ .b8 65
+ .b8 100
+ .b8 100
+ .b8 95
+ .b8 107
+ .b8 101
+ .b8 114
+ .b8 110
+ .b8 101
+ .b8 108
+
+ .b8 0
+ .b8 1
+ .b8 21
+ .b32 278
+ .b8 1
+ .b64 func_begin0
+ .b64 func_end0
+ .b8 1
+ .b8 156
+ .b8 3
+
+ .b8 65
+
+ .b8 0
+ .b8 1
+ .b8 21
+ .b32 284
+ .b8 9
+ .b8 3
+ .b64 VecAdd_kernel_param_0
+ .b8 7
+ .b8 3
+
+ .b8 66
+
+ .b8 0
+ .b8 1
+ .b8 21
+ .b32 284
+ .b8 9
+ .b8 3
+ .b64 VecAdd_kernel_param_1
+ .b8 7
+ .b8 3
+
+ .b8 67
+
+ .b8 0
+ .b8 1
+ .b8 21
+ .b32 304
+ .b8 9
+ .b8 3
+ .b64 VecAdd_kernel_param_2
+ .b8 7
+ .b8 3
+
+ .b8 78
+
+ .b8 0
+ .b8 1
+ .b8 21
+ .b32 310
+ .b8 9
+ .b8 3
+ .b64 VecAdd_kernel_param_3
+ .b8 7
+ .b8 4
+
+ .b64 tmp0
+ .b64 tmp4
+ .b8 5
+
+ .b8 105
+
+ .b8 0
+ .b8 1
+ .b8 23
+ .b32 310
+ .b8 5
+ .b8 144
+ .b8 177
+ .b8 228
+ .b8 149
+ .b8 1
+ .b8 2
+ .b8 0
+ .b8 0
+ .b8 6
+
+ .b8 118
+ .b8 111
+ .b8 105
+ .b8 100
+
+ .b8 0
+ .b8 7
+
+ .b32 290
+ .b8 12
+ .b8 8
+
+ .b32 295
+ .b8 9
+
+ .b8 102
+ .b8 108
+ .b8 111
+ .b8 97
+ .b8 116
+
+ .b8 0
+ .b8 4
+ .b8 4
+ .b8 7
+
+ .b32 295
+ .b8 12
+ .b8 9
+
+ .b8 105
+ .b8 110
+ .b8 116
+
+ .b8 0
+ .b8 5
+ .b8 4
+ .b8 0
+}
+.section .debug_abbrev {
+ .b8 1
+
+ .b8 17
+
+ .b8 1
+
+ .b8 37
+
+ .b8 8
+
+ .b8 19
+
+ .b8 11
+
+ .b8 3
+
+ .b8 8
+
+ .b8 17
+
+ .b8 1
+
+ .b8 16
+
+ .b8 6
+
+ .b8 27
+
+ .b8 8
+
+ .b8 0
+
+ .b8 0
+
+ .b8 2
+
+ .b8 46
+
+ .b8 1
+
+ .b8 135
+ .b8 64
+
+ .b8 8
+
+ .b8 3
+
+ .b8 8
+
+ .b8 58
+
+ .b8 11
+
+ .b8 59
+
+ .b8 11
+
+ .b8 73
+
+ .b8 19
+
+ .b8 63
+
+ .b8 12
+
+ .b8 17
+
+ .b8 1
+
+ .b8 18
+
+ .b8 1
+
+ .b8 64
+
+ .b8 10
+
+ .b8 0
+
+ .b8 0
+
+ .b8 3
+
+ .b8 5
+
+ .b8 0
+
+ .b8 3
+
+ .b8 8
+
+ .b8 58
+
+ .b8 11
+
+ .b8 59
+
+ .b8 11
+
+ .b8 73
+
+ .b8 19
+
+ .b8 2
+
+ .b8 10
+
+ .b8 51
+
+ .b8 11
+
+ .b8 0
+
+ .b8 0
+
+ .b8 4
+
+ .b8 11
+
+ .b8 1
+
+ .b8 17
+
+ .b8 1
+
+ .b8 18
+
+ .b8 1
+
+ .b8 0
+
+ .b8 0
+
+ .b8 5
+
+ .b8 52
+
+ .b8 0
+
+ .b8 3
+
+ .b8 8
+
+ .b8 58
+
+ .b8 11
+
+ .b8 59
+
+ .b8 11
+
+ .b8 73
+
+ .b8 19
+
+ .b8 2
+
+ .b8 10
+
+ .b8 51
+
+ .b8 11
+
+ .b8 0
+
+ .b8 0
+
+ .b8 6
+
+ .b8 59
+
+ .b8 0
+
+ .b8 3
+
+ .b8 8
+
+ .b8 0
+
+ .b8 0
+
+ .b8 7
+
+ .b8 15
+
+ .b8 0
+
+ .b8 73
+
+ .b8 19
+
+ .b8 51
+
+ .b8 11
+
+ .b8 0
+
+ .b8 0
+
+ .b8 8
+
+ .b8 38
+
+ .b8 0
+
+ .b8 73
+
+ .b8 19
+
+ .b8 0
+
+ .b8 0
+
+ .b8 9
+
+ .b8 36
+
+ .b8 0
+
+ .b8 3
+
+ .b8 8
+
+ .b8 62
+
+ .b8 11
+
+ .b8 11
+
+ .b8 11
+
+ .b8 0
+
+ .b8 0
+
+ .b8 0
+
+}
+.section .debug_ranges {
+}
+.section .debug_pubnames {
+ .b32 32
+ .b8 2
+ .b8 0
+ .b32 .debug_info
+ .b32 314
+ .b32 109
+ .b8 86
+ .b8 101
+ .b8 99
+ .b8 65
+ .b8 100
+ .b8 100
+ .b8 95
+ .b8 107
+ .b8 101
+ .b8 114
+ .b8 110
+ .b8 101
+ .b8 108
+ .b8 0
+
+ .b32 0
+}
diff --git a/ptx/src/translate.rs b/ptx/src/translate.rs
new file mode 100644
index 0000000..700bdcd
--- /dev/null
+++ b/ptx/src/translate.rs
@@ -0,0 +1,7647 @@
+use crate::ast;
+use half::f16;
+use rspirv::dr;
+use std::{borrow::Cow, collections::BTreeSet, ffi::CString, hash::Hash, iter, mem};
+use std::{
+ collections::{hash_map, HashMap, HashSet},
+ convert::TryInto,
+};
+
+use rspirv::binary::Assemble;
+
+static ZLUDA_PTX_IMPL: &'static [u8] = include_bytes!("../lib/zluda_ptx_impl.spv");
+
+quick_error! {
+ #[derive(Debug)]
+ pub enum TranslateError {
+ UnknownSymbol {}
+ UntypedSymbol {}
+ MismatchedType {}
+ Spirv(err: rspirv::dr::Error) {
+ from()
+ display("{}", err)
+ cause(err)
+ }
+ Unreachable {}
+ Todo {}
+ }
+}
+
+#[cfg(debug_assertions)]
+fn error_unreachable() -> TranslateError {
+ unreachable!()
+}
+
+#[cfg(not(debug_assertions))]
+fn error_unreachable() -> TranslateError {
+ TranslateError::Unreachable
+}
+
+#[derive(PartialEq, Eq, Hash, Clone)]
+enum SpirvType {
+ Base(SpirvScalarKey),
+ Vector(SpirvScalarKey, u8),
+ Array(SpirvScalarKey, Vec<u32>),
+ Pointer(Box<SpirvType>, spirv::StorageClass),
+ Func(Option<Box<SpirvType>>, Vec<SpirvType>),
+ Struct(Vec<SpirvScalarKey>),
+}
+
+impl SpirvType {
+ fn new_pointer(t: ast::Type, sc: spirv::StorageClass) -> Self {
+ let key = t.into();
+ SpirvType::Pointer(Box::new(key), sc)
+ }
+}
+
+impl From<ast::Type> for SpirvType {
+ fn from(t: ast::Type) -> Self {
+ match t {
+ ast::Type::Scalar(t) => SpirvType::Base(t.into()),
+ ast::Type::Vector(typ, len) => SpirvType::Vector(typ.into(), len),
+ ast::Type::Array(t, len) => SpirvType::Array(t.into(), len),
+ ast::Type::Pointer(pointer_t, state_space) => SpirvType::Pointer(
+ Box::new(SpirvType::from(ast::Type::from(pointer_t))),
+ state_space.to_spirv(),
+ ),
+ }
+ }
+}
+
+impl From<ast::PointerType> for ast::Type {
+ fn from(t: ast::PointerType) -> Self {
+ match t {
+ ast::PointerType::Scalar(t) => ast::Type::Scalar(t),
+ ast::PointerType::Vector(t, len) => ast::Type::Vector(t, len),
+ ast::PointerType::Array(t, dims) => ast::Type::Array(t, dims),
+ ast::PointerType::Pointer(t, space) => {
+ ast::Type::Pointer(ast::PointerType::Scalar(t), space)
+ }
+ }
+ }
+}
+
+impl ast::Type {
+ fn param_pointer_to(self, space: ast::LdStateSpace) -> Result<Self, TranslateError> {
+ Ok(match self {
+ ast::Type::Scalar(t) => ast::Type::Pointer(ast::PointerType::Scalar(t), space),
+ ast::Type::Vector(t, len) => {
+ ast::Type::Pointer(ast::PointerType::Vector(t, len), space)
+ }
+ ast::Type::Array(t, _) => ast::Type::Pointer(ast::PointerType::Scalar(t), space),
+ ast::Type::Pointer(ast::PointerType::Scalar(t), space) => {
+ ast::Type::Pointer(ast::PointerType::Pointer(t, space), space)
+ }
+ ast::Type::Pointer(_, _) => return Err(error_unreachable()),
+ })
+ }
+}
+
+impl Into<spirv::StorageClass> for ast::PointerStateSpace {
+ fn into(self) -> spirv::StorageClass {
+ match self {
+ ast::PointerStateSpace::Const => spirv::StorageClass::UniformConstant,
+ ast::PointerStateSpace::Global => spirv::StorageClass::CrossWorkgroup,
+ ast::PointerStateSpace::Shared => spirv::StorageClass::Workgroup,
+ ast::PointerStateSpace::Param => spirv::StorageClass::Function,
+ ast::PointerStateSpace::Generic => spirv::StorageClass::Generic,
+ }
+ }
+}
+
+impl From<ast::ScalarType> for SpirvType {
+ fn from(t: ast::ScalarType) -> Self {
+ SpirvType::Base(t.into())
+ }
+}
+
+struct TypeWordMap {
+ void: spirv::Word,
+ complex: HashMap<SpirvType, spirv::Word>,
+ constants: HashMap<(SpirvType, u64), spirv::Word>,
+}
+
+// SPIR-V integer type definitions are signless, more below:
+// https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#_a_id_unsignedsigned_a_unsigned_versus_signed_integers
+// https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#_validation_rules_for_kernel_a_href_capability_capabilities_a
+#[derive(PartialEq, Eq, Hash, Clone, Copy)]
+enum SpirvScalarKey {
+ B8,
+ B16,
+ B32,
+ B64,
+ F16,
+ F32,
+ F64,
+ Pred,
+ F16x2,
+}
+
+impl From<ast::ScalarType> for SpirvScalarKey {
+ fn from(t: ast::ScalarType) -> Self {
+ match t {
+ ast::ScalarType::B8 | ast::ScalarType::U8 | ast::ScalarType::S8 => SpirvScalarKey::B8,
+ ast::ScalarType::B16 | ast::ScalarType::U16 | ast::ScalarType::S16 => {
+ SpirvScalarKey::B16
+ }
+ ast::ScalarType::B32 | ast::ScalarType::U32 | ast::ScalarType::S32 => {
+ SpirvScalarKey::B32
+ }
+ ast::ScalarType::B64 | ast::ScalarType::U64 | ast::ScalarType::S64 => {
+ SpirvScalarKey::B64
+ }
+ ast::ScalarType::F16 => SpirvScalarKey::F16,
+ ast::ScalarType::F32 => SpirvScalarKey::F32,
+ ast::ScalarType::F64 => SpirvScalarKey::F64,
+ ast::ScalarType::F16x2 => SpirvScalarKey::F16x2,
+ ast::ScalarType::Pred => SpirvScalarKey::Pred,
+ }
+ }
+}
+
+impl TypeWordMap {
+ fn new(b: &mut dr::Builder) -> TypeWordMap {
+ let void = b.type_void();
+ TypeWordMap {
+ void: void,
+ complex: HashMap::<SpirvType, spirv::Word>::new(),
+ constants: HashMap::new(),
+ }
+ }
+
+ fn void(&self) -> spirv::Word {
+ self.void
+ }
+
+ fn get_or_add_scalar(&mut self, b: &mut dr::Builder, t: ast::ScalarType) -> spirv::Word {
+ let key: SpirvScalarKey = t.into();
+ self.get_or_add_spirv_scalar(b, key)
+ }
+
+ fn get_or_add_spirv_scalar(&mut self, b: &mut dr::Builder, key: SpirvScalarKey) -> spirv::Word {
+ *self
+ .complex
+ .entry(SpirvType::Base(key))
+ .or_insert_with(|| match key {
+ SpirvScalarKey::B8 => b.type_int(8, 0),
+ SpirvScalarKey::B16 => b.type_int(16, 0),
+ SpirvScalarKey::B32 => b.type_int(32, 0),
+ SpirvScalarKey::B64 => b.type_int(64, 0),
+ SpirvScalarKey::F16 => b.type_float(16),
+ SpirvScalarKey::F32 => b.type_float(32),
+ SpirvScalarKey::F64 => b.type_float(64),
+ SpirvScalarKey::Pred => b.type_bool(),
+ SpirvScalarKey::F16x2 => todo!(),
+ })
+ }
+
+ fn get_or_add(&mut self, b: &mut dr::Builder, t: SpirvType) -> spirv::Word {
+ match t {
+ SpirvType::Base(key) => self.get_or_add_spirv_scalar(b, key),
+ SpirvType::Pointer(ref typ, storage) => {
+ let base = self.get_or_add(b, *typ.clone());
+ *self
+ .complex
+ .entry(t)
+ .or_insert_with(|| b.type_pointer(None, storage, base))
+ }
+ SpirvType::Vector(typ, len) => {
+ let base = self.get_or_add_spirv_scalar(b, typ);
+ *self
+ .complex
+ .entry(t)
+ .or_insert_with(|| b.type_vector(base, len as u32))
+ }
+ SpirvType::Array(typ, array_dimensions) => {
+ let u32_type = self.get_or_add_scalar(b, ast::ScalarType::U32);
+ let (base_type, length) = match &*array_dimensions {
+ &[len] => {
+ let base = self.get_or_add_spirv_scalar(b, typ);
+ let len_const = b.constant_u32(u32_type, None, len);
+ (base, len_const)
+ }
+ array_dimensions => {
+ let base = self
+ .get_or_add(b, SpirvType::Array(typ, array_dimensions[1..].to_vec()));
+ let len_const = b.constant_u32(u32_type, None, array_dimensions[0]);
+ (base, len_const)
+ }
+ };
+ *self
+ .complex
+ .entry(SpirvType::Array(typ, array_dimensions))
+ .or_insert_with(|| b.type_array(base_type, length))
+ }
+ SpirvType::Func(ref out_params, ref in_params) => {
+ let out_t = match out_params {
+ Some(p) => self.get_or_add(b, *p.clone()),
+ None => self.void(),
+ };
+ let in_t = in_params
+ .iter()
+ .map(|t| self.get_or_add(b, t.clone()))
+ .collect::<Vec<_>>();
+ *self
+ .complex
+ .entry(t)
+ .or_insert_with(|| b.type_function(out_t, in_t))
+ }
+ SpirvType::Struct(ref underlying) => {
+ let underlying_ids = underlying
+ .iter()
+ .map(|t| self.get_or_add_spirv_scalar(b, *t))
+ .collect::<Vec<_>>();
+ *self
+ .complex
+ .entry(t)
+ .or_insert_with(|| b.type_struct(underlying_ids))
+ }
+ }
+ }
+
+ fn get_or_add_fn(
+ &mut self,
+ b: &mut dr::Builder,
+ in_params: impl ExactSizeIterator<Item = SpirvType>,
+ mut out_params: impl ExactSizeIterator<Item = SpirvType>,
+ ) -> (spirv::Word, spirv::Word) {
+ let (out_args, out_spirv_type) = if out_params.len() == 0 {
+ (None, self.void())
+ } else if out_params.len() == 1 {
+ let arg_as_key = out_params.next().unwrap();
+ (
+ Some(Box::new(arg_as_key.clone())),
+ self.get_or_add(b, arg_as_key),
+ )
+ } else {
+ todo!()
+ };
+ (
+ out_spirv_type,
+ self.get_or_add(b, SpirvType::Func(out_args, in_params.collect::<Vec<_>>())),
+ )
+ }
+
+ fn get_or_add_constant(
+ &mut self,
+ b: &mut dr::Builder,
+ typ: &ast::Type,
+ init: &[u8],
+ ) -> Result<spirv::Word, TranslateError> {
+ Ok(match typ {
+ ast::Type::Scalar(t) => match t {
+ ast::ScalarType::B8 | ast::ScalarType::U8 | ast::ScalarType::S8 => self
+ .get_or_add_constant_single::<u8, _, _>(
+ b,
+ *t,
+ init,
+ |v| v as u64,
+ |b, result_type, v| b.constant_u32(result_type, None, v as u32),
+ ),
+ ast::ScalarType::B16 | ast::ScalarType::U16 | ast::ScalarType::S16 => self
+ .get_or_add_constant_single::<u16, _, _>(
+ b,
+ *t,
+ init,
+ |v| v as u64,
+ |b, result_type, v| b.constant_u32(result_type, None, v as u32),
+ ),
+ ast::ScalarType::B32 | ast::ScalarType::U32 | ast::ScalarType::S32 => self
+ .get_or_add_constant_single::<u32, _, _>(
+ b,
+ *t,
+ init,
+ |v| v as u64,
+ |b, result_type, v| b.constant_u32(result_type, None, v),
+ ),
+ ast::ScalarType::B64 | ast::ScalarType::U64 | ast::ScalarType::S64 => self
+ .get_or_add_constant_single::<u64, _, _>(
+ b,
+ *t,
+ init,
+ |v| v,
+ |b, result_type, v| b.constant_u64(result_type, None, v),
+ ),
+ ast::ScalarType::F16 => self.get_or_add_constant_single::<f16, _, _>(
+ b,
+ *t,
+ init,
+ |v| unsafe { mem::transmute::<_, u16>(v) } as u64,
+ |b, result_type, v| b.constant_f32(result_type, None, v.to_f32()),
+ ),
+ ast::ScalarType::F32 => self.get_or_add_constant_single::<f32, _, _>(
+ b,
+ *t,
+ init,
+ |v| unsafe { mem::transmute::<_, u32>(v) } as u64,
+ |b, result_type, v| b.constant_f32(result_type, None, v),
+ ),
+ ast::ScalarType::F64 => self.get_or_add_constant_single::<f64, _, _>(
+ b,
+ *t,
+ init,
+ |v| unsafe { mem::transmute::<_, u64>(v) },
+ |b, result_type, v| b.constant_f64(result_type, None, v),
+ ),
+ ast::ScalarType::F16x2 => return Err(TranslateError::Todo),
+ ast::ScalarType::Pred => self.get_or_add_constant_single::<u8, _, _>(
+ b,
+ *t,
+ init,
+ |v| v as u64,
+ |b, result_type, v| {
+ if v == 0 {
+ b.constant_false(result_type, None)
+ } else {
+ b.constant_true(result_type, None)
+ }
+ },
+ ),
+ },
+ ast::Type::Vector(typ, len) => {
+ let result_type =
+ self.get_or_add(b, SpirvType::Vector(SpirvScalarKey::from(*typ), *len));
+ let size_of_t = typ.size_of();
+ let components = (0..*len)
+ .map(|x| {
+ self.get_or_add_constant(
+ b,
+ &ast::Type::Scalar(*typ),
+ &init[((size_of_t as usize) * (x as usize))..],
+ )
+ })
+ .collect::<Result<Vec<_>, _>>()?;
+ b.constant_composite(result_type, None, &components)
+ }
+ ast::Type::Array(typ, dims) => match dims.as_slice() {
+ [] => return Err(error_unreachable()),
+ [dim] => {
+ let result_type = self
+ .get_or_add(b, SpirvType::Array(SpirvScalarKey::from(*typ), vec![*dim]));
+ let size_of_t = typ.size_of();
+ let components = (0..*dim)
+ .map(|x| {
+ self.get_or_add_constant(
+ b,
+ &ast::Type::Scalar(*typ),
+ &init[((size_of_t as usize) * (x as usize))..],
+ )
+ })
+ .collect::<Result<Vec<_>, _>>()?;
+ b.constant_composite(result_type, None, &components)
+ }
+ [first_dim, rest @ ..] => {
+ let result_type = self.get_or_add(
+ b,
+ SpirvType::Array(SpirvScalarKey::from(*typ), rest.to_vec()),
+ );
+ let size_of_t = rest
+ .iter()
+ .fold(typ.size_of() as u32, |x, y| (x as u32) * (*y));
+ let components = (0..*first_dim)
+ .map(|x| {
+ self.get_or_add_constant(
+ b,
+ &ast::Type::Array(*typ, rest.to_vec()),
+ &init[((size_of_t as usize) * (x as usize))..],
+ )
+ })
+ .collect::<Result<Vec<_>, _>>()?;
+ b.constant_composite(result_type, None, &components)
+ }
+ },
+ ast::Type::Pointer(typ, state_space) => {
+ let base_t = typ.clone().into();
+ let base = self.get_or_add_constant(b, &base_t, &[])?;
+ let result_type = self.get_or_add(
+ b,
+ SpirvType::Pointer(
+ Box::new(SpirvType::from(base_t)),
+ (*state_space).to_spirv(),
+ ),
+ );
+ b.variable(result_type, None, (*state_space).to_spirv(), Some(base))
+ }
+ })
+ }
+
+ fn get_or_add_constant_single<
+ T: Copy,
+ CastAsU64: FnOnce(T) -> u64,
+ InsertConstant: FnOnce(&mut dr::Builder, spirv::Word, T) -> spirv::Word,
+ >(
+ &mut self,
+ b: &mut dr::Builder,
+ key: ast::ScalarType,
+ init: &[u8],
+ cast: CastAsU64,
+ f: InsertConstant,
+ ) -> spirv::Word {
+ let value = unsafe { *(init.as_ptr() as *const T) };
+ let value_64 = cast(value);
+ let ht_key = (SpirvType::Base(SpirvScalarKey::from(key)), value_64);
+ match self.constants.get(&ht_key) {
+ Some(value) => *value,
+ None => {
+ let spirv_type = self.get_or_add_scalar(b, key);
+ let result = f(b, spirv_type, value);
+ self.constants.insert(ht_key, result);
+ result
+ }
+ }
+ }
+}
+
+pub struct Module {
+ pub spirv: dr::Module,
+ pub kernel_info: HashMap<String, KernelInfo>,
+ pub should_link_ptx_impl: Option<&'static [u8]>,
+ pub build_options: CString,
+}
+impl Module {
+ pub fn assemble(&self) -> Vec<u32> {
+ self.spirv.assemble()
+ }
+}
+
+pub struct KernelInfo {
+ pub arguments_sizes: Vec<usize>,
+ pub uses_shared_mem: bool,
+}
+
+pub fn to_spirv_module<'a>(ast: ast::Module<'a>) -> Result<Module, TranslateError> {
+ let mut id_defs = GlobalStringIdResolver::new(1);
+ let mut ptx_impl_imports = HashMap::new();
+ let directives = ast
+ .directives
+ .into_iter()
+ .filter_map(|directive| {
+ translate_directive(&mut id_defs, &mut ptx_impl_imports, directive).transpose()
+ })
+ .collect::<Result<Vec<_>, _>>()?;
+ let must_link_ptx_impl = ptx_impl_imports.len() > 0;
+ let directives = ptx_impl_imports
+ .into_iter()
+ .map(|(_, v)| v)
+ .chain(directives.into_iter())
+ .collect::<Vec<_>>();
+ let mut builder = dr::Builder::new();
+ builder.reserve_ids(id_defs.current_id());
+ let call_map = get_call_map(&directives);
+ let mut directives = convert_dynamic_shared_memory_usage(directives, &mut || builder.id());
+ normalize_variable_decls(&mut directives);
+ let denorm_information = compute_denorm_information(&directives);
+ // https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#_a_id_logicallayout_a_logical_layout_of_a_module
+ builder.set_version(1, 3);
+ emit_capabilities(&mut builder);
+ emit_extensions(&mut builder);
+ let opencl_id = emit_opencl_import(&mut builder);
+ emit_memory_model(&mut builder);
+ let mut map = TypeWordMap::new(&mut builder);
+ emit_builtins(&mut builder, &mut map, &id_defs);
+ let mut kernel_info = HashMap::new();
+ let build_options = emit_denorm_build_string(&call_map, &denorm_information);
+ emit_directives(
+ &mut builder,
+ &mut map,
+ &id_defs,
+ opencl_id,
+ &denorm_information,
+ &call_map,
+ directives,
+ &mut kernel_info,
+ )?;
+ let spirv = builder.module();
+ Ok(Module {
+ spirv,
+ kernel_info,
+ should_link_ptx_impl: if must_link_ptx_impl {
+ Some(ZLUDA_PTX_IMPL)
+ } else {
+ None
+ },
+ build_options,
+ })
+}
+
+// TODO: remove this once we have perf-function support for denorms
+fn emit_denorm_build_string(
+ call_map: &HashMap<&str, HashSet<u32>>,
+ denorm_information: &HashMap<MethodName, HashMap<u8, (spirv::FPDenormMode, isize)>>,
+) -> CString {
+ let denorm_counts = denorm_information
+ .iter()
+ .map(|(method, meth_denorm)| {
+ let f16_count = meth_denorm
+ .get(&(mem::size_of::<f16>() as u8))
+ .unwrap_or(&(spirv::FPDenormMode::FlushToZero, 0))
+ .1;
+ let f32_count = meth_denorm
+ .get(&(mem::size_of::<f32>() as u8))
+ .unwrap_or(&(spirv::FPDenormMode::FlushToZero, 0))
+ .1;
+ (method, (f16_count + f32_count))
+ })
+ .collect::<HashMap<_, _>>();
+ let mut flush_over_preserve = 0;
+ for (kernel, children) in call_map {
+ flush_over_preserve += *denorm_counts.get(&MethodName::Kernel(kernel)).unwrap_or(&0);
+ for child_fn in children {
+ flush_over_preserve += *denorm_counts
+ .get(&MethodName::Func(*child_fn))
+ .unwrap_or(&0);
+ }
+ }
+ if flush_over_preserve > 0 {
+ CString::new("-cl-denorms-are-zero").unwrap()
+ } else {
+ CString::default()
+ }
+}
+
+fn emit_directives<'input>(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ id_defs: &GlobalStringIdResolver<'input>,
+ opencl_id: spirv::Word,
+ denorm_information: &HashMap<MethodName<'input>, HashMap<u8, (spirv::FPDenormMode, isize)>>,
+ call_map: &HashMap<&'input str, HashSet<spirv::Word>>,
+ directives: Vec<Directive>,
+ kernel_info: &mut HashMap<String, KernelInfo>,
+) -> Result<(), TranslateError> {
+ let empty_body = Vec::new();
+ for d in directives.iter() {
+ match d {
+ Directive::Variable(var) => {
+ emit_variable(builder, map, &var)?;
+ }
+ Directive::Method(f) => {
+ let f_body = match &f.body {
+ Some(f) => f,
+ None => {
+ if f.import_as.is_some() {
+ &empty_body
+ } else {
+ continue;
+ }
+ }
+ };
+ for var in f.globals.iter() {
+ emit_variable(builder, map, var)?;
+ }
+ emit_function_header(
+ builder,
+ map,
+ &id_defs,
+ &f.globals,
+ &f.spirv_decl,
+ &denorm_information,
+ call_map,
+ &directives,
+ kernel_info,
+ )?;
+ emit_function_body_ops(builder, map, opencl_id, &f_body)?;
+ builder.end_function()?;
+ if let (ast::MethodDecl::Func(_, fn_id, _), Some(name)) =
+ (&f.func_decl, &f.import_as)
+ {
+ builder.decorate(
+ *fn_id,
+ spirv::Decoration::LinkageAttributes,
+ &[
+ dr::Operand::LiteralString(name.clone()),
+ dr::Operand::LinkageType(spirv::LinkageType::Import),
+ ],
+ );
+ }
+ }
+ }
+ }
+ Ok(())
+}
+
+fn get_call_map<'input>(
+ module: &[Directive<'input>],
+) -> HashMap<&'input str, HashSet<spirv::Word>> {
+ let mut directly_called_by = HashMap::new();
+ for directive in module {
+ match directive {
+ Directive::Method(Function {
+ func_decl,
+ body: Some(statements),
+ ..
+ }) => {
+ let call_key = MethodName::new(&func_decl);
+ if let hash_map::Entry::Vacant(entry) = directly_called_by.entry(call_key) {
+ entry.insert(Vec::new());
+ }
+ for statement in statements {
+ match statement {
+ Statement::Call(call) => {
+ multi_hash_map_append(&mut directly_called_by, call_key, call.func);
+ }
+ _ => {}
+ }
+ }
+ }
+ _ => {}
+ }
+ }
+ let mut result = HashMap::new();
+ for (method_key, children) in directly_called_by.iter() {
+ match method_key {
+ MethodName::Kernel(name) => {
+ let mut visited = HashSet::new();
+ for child in children {
+ add_call_map_single(&directly_called_by, &mut visited, *child);
+ }
+ result.insert(*name, visited);
+ }
+ MethodName::Func(_) => {}
+ }
+ }
+ result
+}
+
+fn add_call_map_single<'input>(
+ directly_called_by: &MultiHashMap<MethodName<'input>, spirv::Word>,
+ visited: &mut HashSet<spirv::Word>,
+ current: spirv::Word,
+) {
+ if !visited.insert(current) {
+ return;
+ }
+ if let Some(children) = directly_called_by.get(&MethodName::Func(current)) {
+ for child in children {
+ add_call_map_single(directly_called_by, visited, *child);
+ }
+ }
+}
+
+type MultiHashMap<K, V> = HashMap<K, Vec<V>>;
+
+fn multi_hash_map_append<K: Eq + std::hash::Hash, V>(m: &mut MultiHashMap<K, V>, key: K, value: V) {
+ match m.entry(key) {
+ hash_map::Entry::Occupied(mut entry) => {
+ entry.get_mut().push(value);
+ }
+ hash_map::Entry::Vacant(entry) => {
+ entry.insert(vec![value]);
+ }
+ }
+}
+
+// PTX represents dynamically allocated shared local memory as
+// .extern .shared .align 4 .b8 shared_mem[];
+// In SPIRV/OpenCL world this is expressed as an additional argument
+// This pass looks for all uses of .extern .shared and converts them to
+// an additional method argument
+fn convert_dynamic_shared_memory_usage<'input>(
+ module: Vec<Directive<'input>>,
+ new_id: &mut impl FnMut() -> spirv::Word,
+) -> Vec<Directive<'input>> {
+ let mut extern_shared_decls = HashMap::new();
+ for dir in module.iter() {
+ match dir {
+ Directive::Variable(var) => {
+ if let ast::VariableType::Shared(ast::VariableGlobalType::Pointer(p_type, _)) =
+ var.v_type
+ {
+ extern_shared_decls.insert(var.name, p_type);
+ }
+ }
+ _ => {}
+ }
+ }
+ if extern_shared_decls.len() == 0 {
+ return module;
+ }
+ let mut methods_using_extern_shared = HashSet::new();
+ let mut directly_called_by = MultiHashMap::new();
+ let module = module
+ .into_iter()
+ .map(|directive| match directive {
+ Directive::Method(Function {
+ func_decl,
+ globals,
+ body: Some(statements),
+ import_as,
+ spirv_decl,
+ }) => {
+ let call_key = MethodName::new(&func_decl);
+ let statements = statements
+ .into_iter()
+ .map(|statement| match statement {
+ Statement::Call(call) => {
+ multi_hash_map_append(&mut directly_called_by, call.func, call_key);
+ Statement::Call(call)
+ }
+ statement => statement.map_id(&mut |id, _| {
+ if extern_shared_decls.contains_key(&id) {
+ methods_using_extern_shared.insert(call_key);
+ }
+ id
+ }),
+ })
+ .collect();
+ Directive::Method(Function {
+ func_decl,
+ globals,
+ body: Some(statements),
+ import_as,
+ spirv_decl,
+ })
+ }
+ directive => directive,
+ })
+ .collect::<Vec<_>>();
+ // If there's a chain `kernel` -> `fn1` -> `fn2`, where only `fn2` uses extern shared,
+ // make sure it gets propagated to `fn1` and `kernel`
+ get_callers_of_extern_shared(&mut methods_using_extern_shared, &directly_called_by);
+ // now visit every method declaration and inject those additional arguments
+ module
+ .into_iter()
+ .map(|directive| match directive {
+ Directive::Method(Function {
+ func_decl,
+ globals,
+ body: Some(statements),
+ import_as,
+ mut spirv_decl,
+ }) => {
+ if !methods_using_extern_shared.contains(&spirv_decl.name) {
+ return Directive::Method(Function {
+ func_decl,
+ globals,
+ body: Some(statements),
+ import_as,
+ spirv_decl,
+ });
+ }
+ let shared_id_param = new_id();
+ spirv_decl.input.push({
+ ast::Variable {
+ align: None,
+ v_type: ast::Type::Pointer(
+ ast::PointerType::Scalar(ast::ScalarType::U8),
+ ast::LdStateSpace::Shared,
+ ),
+ array_init: Vec::new(),
+ name: shared_id_param,
+ }
+ });
+ spirv_decl.uses_shared_mem = true;
+ let shared_var_id = new_id();
+ let shared_var = ExpandedStatement::Variable(ast::Variable {
+ align: None,
+ name: shared_var_id,
+ array_init: Vec::new(),
+ v_type: ast::VariableType::Reg(ast::VariableRegType::Pointer(
+ ast::SizedScalarType::B8,
+ ast::PointerStateSpace::Shared,
+ )),
+ });
+ let shared_var_st = ExpandedStatement::StoreVar(StoreVarDetails {
+ arg: ast::Arg2St {
+ src1: shared_var_id,
+ src2: shared_id_param,
+ },
+ typ: ast::Type::Scalar(ast::ScalarType::B8),
+ member_index: None,
+ });
+ let mut new_statements = vec![shared_var, shared_var_st];
+ replace_uses_of_shared_memory(
+ &mut new_statements,
+ new_id,
+ &extern_shared_decls,
+ &mut methods_using_extern_shared,
+ shared_id_param,
+ shared_var_id,
+ statements,
+ );
+ Directive::Method(Function {
+ func_decl,
+ globals,
+ body: Some(new_statements),
+ import_as,
+ spirv_decl,
+ })
+ }
+ directive => directive,
+ })
+ .collect::<Vec<_>>()
+}
+
+fn replace_uses_of_shared_memory<'a>(
+ result: &mut Vec<ExpandedStatement>,
+ new_id: &mut impl FnMut() -> spirv::Word,
+ extern_shared_decls: &HashMap<spirv::Word, ast::SizedScalarType>,
+ methods_using_extern_shared: &mut HashSet<MethodName<'a>>,
+ shared_id_param: spirv::Word,
+ shared_var_id: spirv::Word,
+ statements: Vec<ExpandedStatement>,
+) {
+ for statement in statements {
+ match statement {
+ Statement::Call(mut call) => {
+ // We can safely skip checking call arguments,
+ // because there's simply no way to pass shared ptr
+ // without converting it to .b64 first
+ if methods_using_extern_shared.contains(&MethodName::Func(call.func)) {
+ call.param_list
+ .push((shared_id_param, ast::FnArgumentType::Shared));
+ }
+ result.push(Statement::Call(call))
+ }
+ statement => {
+ let new_statement = statement.map_id(&mut |id, _| {
+ if let Some(typ) = extern_shared_decls.get(&id) {
+ if *typ == ast::SizedScalarType::B8 {
+ return shared_var_id;
+ }
+ let replacement_id = new_id();
+ result.push(Statement::Conversion(ImplicitConversion {
+ src: shared_var_id,
+ dst: replacement_id,
+ from: ast::Type::Pointer(
+ ast::PointerType::Scalar(ast::ScalarType::B8),
+ ast::LdStateSpace::Shared,
+ ),
+ to: ast::Type::Pointer(
+ ast::PointerType::Scalar((*typ).into()),
+ ast::LdStateSpace::Shared,
+ ),
+ kind: ConversionKind::PtrToPtr { spirv_ptr: true },
+ src_sema: ArgumentSemantics::Default,
+ dst_sema: ArgumentSemantics::Default,
+ }));
+ replacement_id
+ } else {
+ id
+ }
+ });
+ result.push(new_statement);
+ }
+ }
+ }
+}
+
+fn get_callers_of_extern_shared<'a>(
+ methods_using_extern_shared: &mut HashSet<MethodName<'a>>,
+ directly_called_by: &MultiHashMap<spirv::Word, MethodName<'a>>,
+) {
+ let direct_uses_of_extern_shared = methods_using_extern_shared
+ .iter()
+ .filter_map(|method| {
+ if let MethodName::Func(f_id) = method {
+ Some(*f_id)
+ } else {
+ None
+ }
+ })
+ .collect::<Vec<_>>();
+ for fn_id in direct_uses_of_extern_shared {
+ get_callers_of_extern_shared_single(methods_using_extern_shared, directly_called_by, fn_id);
+ }
+}
+
+fn get_callers_of_extern_shared_single<'a>(
+ methods_using_extern_shared: &mut HashSet<MethodName<'a>>,
+ directly_called_by: &MultiHashMap<spirv::Word, MethodName<'a>>,
+ fn_id: spirv::Word,
+) {
+ if let Some(callers) = directly_called_by.get(&fn_id) {
+ for caller in callers {
+ if methods_using_extern_shared.insert(*caller) {
+ if let MethodName::Func(caller_fn) = caller {
+ get_callers_of_extern_shared_single(
+ methods_using_extern_shared,
+ directly_called_by,
+ *caller_fn,
+ );
+ }
+ }
+ }
+ }
+}
+
+type DenormCountMap<T> = HashMap<T, isize>;
+
+fn denorm_count_map_update<T: Eq + Hash>(map: &mut DenormCountMap<T>, key: T, value: bool) {
+ let num_value = if value { 1 } else { -1 };
+ denorm_count_map_update_impl(map, key, num_value);
+}
+
+fn denorm_count_map_update_impl<T: Eq + Hash>(
+ map: &mut DenormCountMap<T>,
+ key: T,
+ num_value: isize,
+) {
+ match map.entry(key) {
+ hash_map::Entry::Occupied(mut counter) => {
+ *(counter.get_mut()) += num_value;
+ }
+ hash_map::Entry::Vacant(entry) => {
+ entry.insert(num_value);
+ }
+ }
+}
+
+// HACK ALERT!
+// This function is a "good enough" heuristic of whetever to mark f16/f32 operations
+// in the kernel as flushing denorms to zero or preserving them
+// PTX support per-instruction ftz information. Unfortunately SPIR-V has no
+// such capability, so instead we guesstimate which use is more common in the kernel
+// and emit suitable execution mode
+fn compute_denorm_information<'input>(
+ module: &[Directive<'input>],
+) -> HashMap<MethodName<'input>, HashMap<u8, (spirv::FPDenormMode, isize)>> {
+ let mut denorm_methods = HashMap::new();
+ for directive in module {
+ match directive {
+ Directive::Variable(_) | Directive::Method(Function { body: None, .. }) => {}
+ Directive::Method(Function {
+ func_decl,
+ body: Some(statements),
+ ..
+ }) => {
+ let mut flush_counter = DenormCountMap::new();
+ let method_key = MethodName::new(func_decl);
+ for statement in statements {
+ match statement {
+ Statement::Instruction(inst) => {
+ if let Some((flush, width)) = inst.flush_to_zero() {
+ denorm_count_map_update(&mut flush_counter, width, flush);
+ }
+ }
+ Statement::LoadVar(..) => {}
+ Statement::StoreVar(..) => {}
+ Statement::Call(_) => {}
+ Statement::Conditional(_) => {}
+ Statement::Conversion(_) => {}
+ Statement::Constant(_) => {}
+ Statement::RetValue(_, _) => {}
+ Statement::Label(_) => {}
+ Statement::Variable(_) => {}
+ Statement::PtrAccess { .. } => {}
+ Statement::RepackVector(_) => {}
+ }
+ }
+ denorm_methods.insert(method_key, flush_counter);
+ }
+ }
+ }
+ denorm_methods
+ .into_iter()
+ .map(|(name, v)| {
+ let width_to_denorm = v
+ .into_iter()
+ .map(|(k, flush_over_preserve)| {
+ let mode = if flush_over_preserve > 0 {
+ spirv::FPDenormMode::FlushToZero
+ } else {
+ spirv::FPDenormMode::Preserve
+ };
+ (k, (mode, flush_over_preserve))
+ })
+ .collect();
+ (name, width_to_denorm)
+ })
+ .collect()
+}
+
+#[derive(Hash, PartialEq, Eq, Copy, Clone)]
+enum MethodName<'input> {
+ Kernel(&'input str),
+ Func(spirv::Word),
+}
+
+impl<'input> MethodName<'input> {
+ fn new(decl: &ast::MethodDecl<'input, spirv::Word>) -> Self {
+ match decl {
+ ast::MethodDecl::Kernel { name, .. } => MethodName::Kernel(name),
+ ast::MethodDecl::Func(_, id, _) => MethodName::Func(*id),
+ }
+ }
+}
+
+fn emit_builtins(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ id_defs: &GlobalStringIdResolver,
+) {
+ for (reg, id) in id_defs.special_registers.builtins() {
+ let result_type = map.get_or_add(
+ builder,
+ SpirvType::Pointer(
+ Box::new(SpirvType::from(reg.get_type())),
+ spirv::StorageClass::Input,
+ ),
+ );
+ builder.variable(result_type, Some(id), spirv::StorageClass::Input, None);
+ builder.decorate(
+ id,
+ spirv::Decoration::BuiltIn,
+ &[dr::Operand::BuiltIn(reg.get_builtin())],
+ );
+ }
+}
+
+fn emit_function_header<'a>(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ defined_globals: &GlobalStringIdResolver<'a>,
+ synthetic_globals: &[ast::Variable<ast::VariableType, spirv::Word>],
+ func_decl: &SpirvMethodDecl<'a>,
+ _denorm_information: &HashMap<MethodName<'a>, HashMap<u8, (spirv::FPDenormMode, isize)>>,
+ call_map: &HashMap<&'a str, HashSet<spirv::Word>>,
+ direcitves: &[Directive],
+ kernel_info: &mut HashMap<String, KernelInfo>,
+) -> Result<(), TranslateError> {
+ if let MethodName::Kernel(name) = func_decl.name {
+ let input_args = if !func_decl.uses_shared_mem {
+ func_decl.input.as_slice()
+ } else {
+ &func_decl.input[0..func_decl.input.len() - 1]
+ };
+ let args_lens = input_args
+ .iter()
+ .map(|param| param.v_type.size_of())
+ .collect();
+ kernel_info.insert(
+ name.to_string(),
+ KernelInfo {
+ arguments_sizes: args_lens,
+ uses_shared_mem: func_decl.uses_shared_mem,
+ },
+ );
+ }
+ let (ret_type, func_type) =
+ get_function_type(builder, map, &func_decl.input, &func_decl.output);
+ let fn_id = match func_decl.name {
+ MethodName::Kernel(name) => {
+ let fn_id = defined_globals.get_id(name)?;
+ let mut global_variables = defined_globals
+ .variables_type_check
+ .iter()
+ .filter_map(|(k, t)| t.as_ref().map(|_| *k))
+ .collect::<Vec<_>>();
+ let mut interface = defined_globals.special_registers.interface();
+ for ast::Variable { name, .. } in synthetic_globals {
+ interface.push(*name);
+ }
+ let empty_hash_set = HashSet::new();
+ let child_fns = call_map.get(name).unwrap_or(&empty_hash_set);
+ for directive in direcitves {
+ match directive {
+ Directive::Method(Function {
+ func_decl: ast::MethodDecl::Func(_, name, _),
+ globals,
+ ..
+ }) => {
+ if child_fns.contains(name) {
+ for var in globals {
+ interface.push(var.name);
+ }
+ }
+ }
+ _ => {}
+ }
+ }
+ global_variables.append(&mut interface);
+ builder.entry_point(spirv::ExecutionModel::Kernel, fn_id, name, global_variables);
+ fn_id
+ }
+ MethodName::Func(name) => name,
+ };
+ builder.begin_function(
+ ret_type,
+ Some(fn_id),
+ spirv::FunctionControl::NONE,
+ func_type,
+ )?;
+ // TODO: re-enable when Intel float control extension works
+ /*
+ if let Some(denorm_modes) = denorm_information.get(&func_decl.name) {
+ for (size_of, denorm_mode) in denorm_modes {
+ builder.decorate(
+ fn_id,
+ spirv::Decoration::FunctionDenormModeINTEL,
+ [
+ dr::Operand::LiteralInt32((*size_of as u32) * 8),
+ dr::Operand::FPDenormMode(*denorm_mode),
+ ],
+ )
+ }
+ }
+ */
+ for input in &func_decl.input {
+ let result_type = map.get_or_add(builder, SpirvType::from(input.v_type.clone()));
+ let inst = dr::Instruction::new(
+ spirv::Op::FunctionParameter,
+ Some(result_type),
+ Some(input.name),
+ Vec::new(),
+ );
+ builder.function.as_mut().unwrap().parameters.push(inst);
+ }
+ Ok(())
+}
+
+fn emit_capabilities(builder: &mut dr::Builder) {
+ builder.capability(spirv::Capability::GenericPointer);
+ builder.capability(spirv::Capability::Linkage);
+ builder.capability(spirv::Capability::Addresses);
+ builder.capability(spirv::Capability::Kernel);
+ builder.capability(spirv::Capability::Int8);
+ builder.capability(spirv::Capability::Int16);
+ builder.capability(spirv::Capability::Int64);
+ builder.capability(spirv::Capability::Float16);
+ builder.capability(spirv::Capability::Float64);
+ // TODO: re-enable when Intel float control extension works
+ //builder.capability(spirv::Capability::FunctionFloatControlINTEL);
+}
+
+// http://htmlpreview.github.io/?https://github.com/KhronosGroup/SPIRV-Registry/blob/master/extensions/KHR/SPV_KHR_float_controls.html
+fn emit_extensions(_builder: &mut dr::Builder) {
+ // TODO: re-enable when Intel float control extension works
+ //builder.extension("SPV_INTEL_float_controls2");
+}
+
+fn emit_opencl_import(builder: &mut dr::Builder) -> spirv::Word {
+ builder.ext_inst_import("OpenCL.std")
+}
+
+fn emit_memory_model(builder: &mut dr::Builder) {
+ builder.memory_model(
+ spirv::AddressingModel::Physical64,
+ spirv::MemoryModel::OpenCL,
+ );
+}
+
+fn translate_directive<'input>(
+ id_defs: &mut GlobalStringIdResolver<'input>,
+ ptx_impl_imports: &mut HashMap<String, Directive<'input>>,
+ d: ast::Directive<'input, ast::ParsedArgParams<'input>>,
+) -> Result<Option<Directive<'input>>, TranslateError> {
+ Ok(match d {
+ ast::Directive::Variable(v) => Some(Directive::Variable(translate_variable(id_defs, v)?)),
+ ast::Directive::Method(f) => {
+ translate_function(id_defs, ptx_impl_imports, f)?.map(Directive::Method)
+ }
+ })
+}
+
+fn translate_variable<'a>(
+ id_defs: &mut GlobalStringIdResolver<'a>,
+ var: ast::Variable<ast::VariableType, &'a str>,
+) -> Result<ast::Variable<ast::VariableType, spirv::Word>, TranslateError> {
+ let (space, var_type) = var.v_type.to_type();
+ let mut is_variable = false;
+ let var_type = match space {
+ ast::StateSpace::Reg => {
+ is_variable = true;
+ var_type
+ }
+ ast::StateSpace::Const => var_type.param_pointer_to(ast::LdStateSpace::Const)?,
+ ast::StateSpace::Global => var_type.param_pointer_to(ast::LdStateSpace::Global)?,
+ ast::StateSpace::Local => var_type.param_pointer_to(ast::LdStateSpace::Local)?,
+ ast::StateSpace::Shared => {
+ // If it's a pointer it will be translated to a method parameter later
+ if let ast::Type::Pointer(..) = var_type {
+ is_variable = true;
+ var_type
+ } else {
+ var_type.param_pointer_to(ast::LdStateSpace::Shared)?
+ }
+ }
+ ast::StateSpace::Param => var_type.param_pointer_to(ast::LdStateSpace::Param)?,
+ };
+ Ok(ast::Variable {
+ align: var.align,
+ v_type: var.v_type,
+ name: id_defs.get_or_add_def_typed(var.name, var_type, is_variable),
+ array_init: var.array_init,
+ })
+}
+
+fn translate_function<'a>(
+ id_defs: &mut GlobalStringIdResolver<'a>,
+ ptx_impl_imports: &mut HashMap<String, Directive<'a>>,
+ f: ast::ParsedFunction<'a>,
+) -> Result<Option<Function<'a>>, TranslateError> {
+ let import_as = match &f.func_directive {
+ ast::MethodDecl::Func(_, "__assertfail", _) => {
+ Some("__zluda_ptx_impl____assertfail".to_owned())
+ }
+ _ => None,
+ };
+ let (str_resolver, fn_resolver, fn_decl) = id_defs.start_fn(&f.func_directive)?;
+ let mut func = to_ssa(ptx_impl_imports, str_resolver, fn_resolver, fn_decl, f.body)?;
+ func.import_as = import_as;
+ if func.import_as.is_some() {
+ ptx_impl_imports.insert(
+ func.import_as.as_ref().unwrap().clone(),
+ Directive::Method(func),
+ );
+ Ok(None)
+ } else {
+ Ok(Some(func))
+ }
+}
+
+fn expand_kernel_params<'a, 'b>(
+ fn_resolver: &mut FnStringIdResolver<'a, 'b>,
+ args: impl Iterator<Item = &'b ast::KernelArgument<&'a str>>,
+) -> Result<Vec<ast::KernelArgument<spirv::Word>>, TranslateError> {
+ args.map(|a| {
+ Ok(ast::KernelArgument {
+ name: fn_resolver.add_def(
+ a.name,
+ Some(ast::Type::from(a.v_type.clone()).param_pointer_to(ast::LdStateSpace::Param)?),
+ false,
+ ),
+ v_type: a.v_type.clone(),
+ align: a.align,
+ array_init: Vec::new(),
+ })
+ })
+ .collect::<Result<_, _>>()
+}
+
+fn expand_fn_params<'a, 'b>(
+ fn_resolver: &mut FnStringIdResolver<'a, 'b>,
+ args: impl Iterator<Item = &'b ast::FnArgument<&'a str>>,
+) -> Result<Vec<ast::FnArgument<spirv::Word>>, TranslateError> {
+ args.map(|a| {
+ let is_variable = match a.v_type {
+ ast::FnArgumentType::Reg(_) => true,
+ _ => false,
+ };
+ let var_type = a.v_type.to_func_type();
+ Ok(ast::FnArgument {
+ name: fn_resolver.add_def(a.name, Some(var_type), is_variable),
+ v_type: a.v_type.clone(),
+ align: a.align,
+ array_init: Vec::new(),
+ })
+ })
+ .collect()
+}
+
+fn to_ssa<'input, 'b>(
+ ptx_impl_imports: &mut HashMap<String, Directive>,
+ mut id_defs: FnStringIdResolver<'input, 'b>,
+ fn_defs: GlobalFnDeclResolver<'input, 'b>,
+ f_args: ast::MethodDecl<'input, spirv::Word>,
+ f_body: Option<Vec<ast::Statement<ast::ParsedArgParams<'input>>>>,
+) -> Result<Function<'input>, TranslateError> {
+ let mut spirv_decl = SpirvMethodDecl::new(&f_args);
+ let f_body = match f_body {
+ Some(vec) => vec,
+ None => {
+ return Ok(Function {
+ func_decl: f_args,
+ body: None,
+ globals: Vec::new(),
+ import_as: None,
+ spirv_decl,
+ })
+ }
+ };
+ let normalized_ids = normalize_identifiers(&mut id_defs, &fn_defs, f_body)?;
+ let mut numeric_id_defs = id_defs.finish();
+ let unadorned_statements = normalize_predicates(normalized_ids, &mut numeric_id_defs)?;
+ let typed_statements =
+ convert_to_typed_statements(unadorned_statements, &fn_defs, &mut numeric_id_defs)?;
+ let typed_statements =
+ convert_to_stateful_memory_access(&mut spirv_decl, typed_statements, &mut numeric_id_defs)?;
+ let ssa_statements = insert_mem_ssa_statements(
+ typed_statements,
+ &mut numeric_id_defs,
+ &f_args,
+ &mut spirv_decl,
+ )?;
+ let ssa_statements = fix_builtins(ssa_statements, &mut numeric_id_defs)?;
+ let mut numeric_id_defs = numeric_id_defs.finish();
+ let expanded_statements = expand_arguments(ssa_statements, &mut numeric_id_defs)?;
+ let expanded_statements =
+ insert_implicit_conversions(expanded_statements, &mut numeric_id_defs)?;
+ let mut numeric_id_defs = numeric_id_defs.unmut();
+ let labeled_statements = normalize_labels(expanded_statements, &mut numeric_id_defs);
+ let (f_body, globals) =
+ extract_globals(labeled_statements, ptx_impl_imports, &mut numeric_id_defs);
+ Ok(Function {
+ func_decl: f_args,
+ globals: globals,
+ body: Some(f_body),
+ import_as: None,
+ spirv_decl,
+ })
+}
+
+fn fix_builtins(
+ typed_statements: Vec<TypedStatement>,
+ numeric_id_defs: &mut NumericIdResolver,
+) -> Result<Vec<TypedStatement>, TranslateError> {
+ let mut result = Vec::with_capacity(typed_statements.len());
+ for s in typed_statements {
+ match s {
+ Statement::LoadVar(
+ mut
+ details
+ @
+ LoadVarDetails {
+ member_index: Some((_, Some(_))),
+ ..
+ },
+ ) => {
+ let index = details.member_index.unwrap().0;
+ if index == 3 {
+ result.push(Statement::Constant(ConstantDefinition {
+ dst: details.arg.dst,
+ typ: ast::ScalarType::U32,
+ value: ast::ImmediateValue::U64(0),
+ }));
+ } else {
+ let sreg_and_type = match numeric_id_defs.special_registers.get(details.arg.src)
+ {
+ Some(reg) => get_sreg_id_scalar_type(numeric_id_defs, reg),
+ None => None,
+ };
+ let (sreg_src, scalar_typ, vector_width) = match sreg_and_type {
+ Some(sreg_and_type) => sreg_and_type,
+ None => {
+ result.push(Statement::LoadVar(details));
+ continue;
+ }
+ };
+ let temp_id = numeric_id_defs.new_non_variable(Some(details.typ.clone()));
+ let real_dst = details.arg.dst;
+ details.arg.dst = temp_id;
+ result.push(Statement::LoadVar(LoadVarDetails {
+ arg: Arg2 {
+ src: sreg_src,
+ dst: temp_id,
+ },
+ typ: ast::Type::Scalar(scalar_typ),
+ member_index: Some((index, Some(vector_width))),
+ }));
+ result.push(Statement::Conversion(ImplicitConversion {
+ src: temp_id,
+ dst: real_dst,
+ from: ast::Type::Scalar(scalar_typ),
+ to: ast::Type::Scalar(ast::ScalarType::U32),
+ kind: ConversionKind::Default,
+ src_sema: ArgumentSemantics::Default,
+ dst_sema: ArgumentSemantics::Default,
+ }));
+ }
+ }
+ s => result.push(s),
+ }
+ }
+ Ok(result)
+}
+
+fn get_sreg_id_scalar_type(
+ numeric_id_defs: &mut NumericIdResolver,
+ sreg: PtxSpecialRegister,
+) -> Option<(spirv::Word, ast::ScalarType, u8)> {
+ match sreg.normalized_sreg_and_type() {
+ Some((normalized_sreg, typ, vec_width)) => Some((
+ numeric_id_defs
+ .special_registers
+ .get_or_add(numeric_id_defs.current_id, normalized_sreg),
+ typ,
+ vec_width,
+ )),
+ None => None,
+ }
+}
+
+fn extract_globals<'input, 'b>(
+ sorted_statements: Vec<ExpandedStatement>,
+ ptx_impl_imports: &mut HashMap<String, Directive>,
+ id_def: &mut NumericIdResolver,
+) -> (
+ Vec<ExpandedStatement>,
+ Vec<ast::Variable<ast::VariableType, spirv::Word>>,
+) {
+ let mut local = Vec::with_capacity(sorted_statements.len());
+ let mut global = Vec::new();
+ for statement in sorted_statements {
+ match statement {
+ Statement::Variable(
+ var
+ @
+ ast::Variable {
+ v_type: ast::VariableType::Shared(_),
+ ..
+ },
+ )
+ | Statement::Variable(
+ var
+ @
+ ast::Variable {
+ v_type: ast::VariableType::Global(_),
+ ..
+ },
+ ) => global.push(var),
+ Statement::Instruction(ast::Instruction::Bfe { typ, arg }) => {
+ local.push(to_ptx_impl_bfe_call(id_def, ptx_impl_imports, typ, arg));
+ }
+ Statement::Instruction(ast::Instruction::Atom(
+ d
+ @
+ ast::AtomDetails {
+ inner:
+ ast::AtomInnerDetails::Unsigned {
+ op: ast::AtomUIntOp::Inc,
+ ..
+ },
+ ..
+ },
+ a,
+ )) => {
+ local.push(to_ptx_impl_atomic_call(
+ id_def,
+ ptx_impl_imports,
+ d,
+ a,
+ "inc",
+ ));
+ }
+ Statement::Instruction(ast::Instruction::Atom(
+ d
+ @
+ ast::AtomDetails {
+ inner:
+ ast::AtomInnerDetails::Unsigned {
+ op: ast::AtomUIntOp::Dec,
+ ..
+ },
+ ..
+ },
+ a,
+ )) => {
+ local.push(to_ptx_impl_atomic_call(
+ id_def,
+ ptx_impl_imports,
+ d,
+ a,
+ "dec",
+ ));
+ }
+ s => local.push(s),
+ }
+ }
+ (local, global)
+}
+
+fn normalize_variable_decls(directives: &mut Vec<Directive>) {
+ for directive in directives {
+ match directive {
+ Directive::Method(Function {
+ body: Some(func), ..
+ }) => {
+ func[1..].sort_by_key(|s| match s {
+ Statement::Variable(_) => 0,
+ _ => 1,
+ });
+ }
+ _ => (),
+ }
+ }
+}
+
+fn convert_to_typed_statements(
+ func: Vec<UnconditionalStatement>,
+ fn_defs: &GlobalFnDeclResolver,
+ id_defs: &mut NumericIdResolver,
+) -> Result<Vec<TypedStatement>, TranslateError> {
+ let mut result = Vec::<TypedStatement>::with_capacity(func.len());
+ for s in func {
+ match s {
+ Statement::Instruction(inst) => match inst {
+ ast::Instruction::Call(call) => {
+ // TODO: error out if lengths don't match
+ let fn_def = fn_defs.get_fn_decl(call.func)?;
+ let out_args = to_resolved_fn_args(call.ret_params, &*fn_def.ret_vals);
+ let in_args = to_resolved_fn_args(call.param_list, &*fn_def.params);
+ let (out_params, out_non_params): (Vec<_>, Vec<_>) = out_args
+ .into_iter()
+ .partition(|(_, arg_type)| arg_type.is_param());
+ let normalized_input_args = out_params
+ .into_iter()
+ .map(|(id, typ)| (ast::Operand::Reg(id), typ))
+ .chain(in_args.into_iter())
+ .collect();
+ let resolved_call = ResolvedCall {
+ uniform: call.uniform,
+ ret_params: out_non_params,
+ func: call.func,
+ param_list: normalized_input_args,
+ };
+ let mut visitor = VectorRepackVisitor::new(&mut result, id_defs);
+ let reresolved_call = resolved_call.visit(&mut visitor)?;
+ visitor.func.push(reresolved_call);
+ visitor.func.extend(visitor.post_stmts);
+ }
+ ast::Instruction::Mov(mut d, ast::Arg2Mov { dst, src }) => {
+ if let Some(src_id) = src.underlying() {
+ let (typ, _) = id_defs.get_typed(*src_id)?;
+ let take_address = match typ {
+ ast::Type::Scalar(_) => false,
+ ast::Type::Vector(_, _) => false,
+ ast::Type::Array(_, _) => true,
+ ast::Type::Pointer(_, _) => true,
+ };
+ d.src_is_address = take_address;
+ }
+ let mut visitor = VectorRepackVisitor::new(&mut result, id_defs);
+ let instruction = Statement::Instruction(
+ ast::Instruction::Mov(d, ast::Arg2Mov { dst, src }).map(&mut visitor)?,
+ );
+ visitor.func.push(instruction);
+ visitor.func.extend(visitor.post_stmts);
+ }
+ inst => {
+ let mut visitor = VectorRepackVisitor::new(&mut result, id_defs);
+ let instruction = Statement::Instruction(inst.map(&mut visitor)?);
+ visitor.func.push(instruction);
+ visitor.func.extend(visitor.post_stmts);
+ }
+ },
+ Statement::Label(i) => result.push(Statement::Label(i)),
+ Statement::Variable(v) => result.push(Statement::Variable(v)),
+ Statement::Conditional(c) => result.push(Statement::Conditional(c)),
+ _ => return Err(error_unreachable()),
+ }
+ }
+ Ok(result)
+}
+
+struct VectorRepackVisitor<'a, 'b> {
+ func: &'b mut Vec<TypedStatement>,
+ id_def: &'b mut NumericIdResolver<'a>,
+ post_stmts: Option<TypedStatement>,
+}
+
+impl<'a, 'b> VectorRepackVisitor<'a, 'b> {
+ fn new(func: &'b mut Vec<TypedStatement>, id_def: &'b mut NumericIdResolver<'a>) -> Self {
+ VectorRepackVisitor {
+ func,
+ id_def,
+ post_stmts: None,
+ }
+ }
+
+ fn convert_vector(
+ &mut self,
+ is_dst: bool,
+ vector_sema: ArgumentSemantics,
+ typ: &ast::Type,
+ idx: Vec<spirv::Word>,
+ ) -> Result<spirv::Word, TranslateError> {
+ // mov.u32 foobar, {a,b};
+ let scalar_t = match typ {
+ ast::Type::Vector(scalar_t, _) => *scalar_t,
+ _ => return Err(TranslateError::MismatchedType),
+ };
+ let temp_vec = self.id_def.new_non_variable(Some(typ.clone()));
+ let statement = Statement::RepackVector(RepackVectorDetails {
+ is_extract: is_dst,
+ typ: scalar_t,
+ packed: temp_vec,
+ unpacked: idx,
+ vector_sema,
+ });
+ if is_dst {
+ self.post_stmts = Some(statement);
+ } else {
+ self.func.push(statement);
+ }
+ Ok(temp_vec)
+ }
+}
+
+impl<'a, 'b> ArgumentMapVisitor<NormalizedArgParams, TypedArgParams>
+ for VectorRepackVisitor<'a, 'b>
+{
+ fn id(
+ &mut self,
+ desc: ArgumentDescriptor<spirv::Word>,
+ _: Option<&ast::Type>,
+ ) -> Result<spirv::Word, TranslateError> {
+ Ok(desc.op)
+ }
+
+ fn operand(
+ &mut self,
+ desc: ArgumentDescriptor<ast::Operand<spirv::Word>>,
+ typ: &ast::Type,
+ ) -> Result<TypedOperand, TranslateError> {
+ Ok(match desc.op {
+ ast::Operand::Reg(reg) => TypedOperand::Reg(reg),
+ ast::Operand::RegOffset(reg, offset) => TypedOperand::RegOffset(reg, offset),
+ ast::Operand::Imm(x) => TypedOperand::Imm(x),
+ ast::Operand::VecMember(vec, idx) => TypedOperand::VecMember(vec, idx),
+ ast::Operand::VecPack(vec) => {
+ TypedOperand::Reg(self.convert_vector(desc.is_dst, desc.sema, typ, vec)?)
+ }
+ })
+ }
+}
+
+//TODO: share common code between this and to_ptx_impl_bfe_call
+fn to_ptx_impl_atomic_call(
+ id_defs: &mut NumericIdResolver,
+ ptx_impl_imports: &mut HashMap<String, Directive>,
+ details: ast::AtomDetails,
+ arg: ast::Arg3<ExpandedArgParams>,
+ op: &'static str,
+) -> ExpandedStatement {
+ let semantics = ptx_semantics_name(details.semantics);
+ let scope = ptx_scope_name(details.scope);
+ let space = ptx_space_name(details.space);
+ let fn_name = format!(
+ "__zluda_ptx_impl__atom_{}_{}_{}_{}",
+ semantics, scope, space, op
+ );
+ // TODO: extract to a function
+ let ptr_space = match details.space {
+ ast::AtomSpace::Generic => ast::PointerStateSpace::Generic,
+ ast::AtomSpace::Global => ast::PointerStateSpace::Global,
+ ast::AtomSpace::Shared => ast::PointerStateSpace::Shared,
+ };
+ let fn_id = match ptx_impl_imports.entry(fn_name) {
+ hash_map::Entry::Vacant(entry) => {
+ let fn_id = id_defs.new_non_variable(None);
+ let func_decl = ast::MethodDecl::Func::<spirv::Word>(
+ vec![ast::FnArgument {
+ align: None,
+ v_type: ast::FnArgumentType::Reg(ast::VariableRegType::Scalar(
+ ast::ScalarType::U32,
+ )),
+ name: id_defs.new_non_variable(None),
+ array_init: Vec::new(),
+ }],
+ fn_id,
+ vec![
+ ast::FnArgument {
+ align: None,
+ v_type: ast::FnArgumentType::Reg(ast::VariableRegType::Pointer(
+ ast::SizedScalarType::U32,
+ ptr_space,
+ )),
+ name: id_defs.new_non_variable(None),
+ array_init: Vec::new(),
+ },
+ ast::FnArgument {
+ align: None,
+ v_type: ast::FnArgumentType::Reg(ast::VariableRegType::Scalar(
+ ast::ScalarType::U32,
+ )),
+ name: id_defs.new_non_variable(None),
+ array_init: Vec::new(),
+ },
+ ],
+ );
+ let spirv_decl = SpirvMethodDecl::new(&func_decl);
+ let func = Function {
+ func_decl,
+ globals: Vec::new(),
+ body: None,
+ import_as: Some(entry.key().clone()),
+ spirv_decl,
+ };
+ entry.insert(Directive::Method(func));
+ fn_id
+ }
+ hash_map::Entry::Occupied(entry) => match entry.get() {
+ Directive::Method(Function {
+ func_decl: ast::MethodDecl::Func(_, name, _),
+ ..
+ }) => *name,
+ _ => unreachable!(),
+ },
+ };
+ Statement::Call(ResolvedCall {
+ uniform: false,
+ func: fn_id,
+ ret_params: vec![(
+ arg.dst,
+ ast::FnArgumentType::Reg(ast::VariableRegType::Scalar(ast::ScalarType::U32)),
+ )],
+ param_list: vec![
+ (
+ arg.src1,
+ ast::FnArgumentType::Reg(ast::VariableRegType::Pointer(
+ ast::SizedScalarType::U32,
+ ptr_space,
+ )),
+ ),
+ (
+ arg.src2,
+ ast::FnArgumentType::Reg(ast::VariableRegType::Scalar(ast::ScalarType::U32)),
+ ),
+ ],
+ })
+}
+
+fn to_ptx_impl_bfe_call(
+ id_defs: &mut NumericIdResolver,
+ ptx_impl_imports: &mut HashMap<String, Directive>,
+ typ: ast::IntType,
+ arg: ast::Arg4<ExpandedArgParams>,
+) -> ExpandedStatement {
+ let prefix = "__zluda_ptx_impl__";
+ let suffix = match typ {
+ ast::IntType::U32 => "bfe_u32",
+ ast::IntType::U64 => "bfe_u64",
+ ast::IntType::S32 => "bfe_s32",
+ ast::IntType::S64 => "bfe_s64",
+ _ => unreachable!(),
+ };
+ let fn_name = format!("{}{}", prefix, suffix);
+ let fn_id = match ptx_impl_imports.entry(fn_name) {
+ hash_map::Entry::Vacant(entry) => {
+ let fn_id = id_defs.new_non_variable(None);
+ let func_decl = ast::MethodDecl::Func::<spirv::Word>(
+ vec![ast::FnArgument {
+ align: None,
+ v_type: ast::FnArgumentType::Reg(ast::VariableRegType::Scalar(typ.into())),
+ name: id_defs.new_non_variable(None),
+ array_init: Vec::new(),
+ }],
+ fn_id,
+ vec![
+ ast::FnArgument {
+ align: None,
+ v_type: ast::FnArgumentType::Reg(ast::VariableRegType::Scalar(typ.into())),
+ name: id_defs.new_non_variable(None),
+ array_init: Vec::new(),
+ },
+ ast::FnArgument {
+ align: None,
+ v_type: ast::FnArgumentType::Reg(ast::VariableRegType::Scalar(
+ ast::ScalarType::U32,
+ )),
+ name: id_defs.new_non_variable(None),
+ array_init: Vec::new(),
+ },
+ ast::FnArgument {
+ align: None,
+ v_type: ast::FnArgumentType::Reg(ast::VariableRegType::Scalar(
+ ast::ScalarType::U32,
+ )),
+ name: id_defs.new_non_variable(None),
+ array_init: Vec::new(),
+ },
+ ],
+ );
+ let spirv_decl = SpirvMethodDecl::new(&func_decl);
+ let func = Function {
+ func_decl,
+ globals: Vec::new(),
+ body: None,
+ import_as: Some(entry.key().clone()),
+ spirv_decl,
+ };
+ entry.insert(Directive::Method(func));
+ fn_id
+ }
+ hash_map::Entry::Occupied(entry) => match entry.get() {
+ Directive::Method(Function {
+ func_decl: ast::MethodDecl::Func(_, name, _),
+ ..
+ }) => *name,
+ _ => unreachable!(),
+ },
+ };
+ Statement::Call(ResolvedCall {
+ uniform: false,
+ func: fn_id,
+ ret_params: vec![(
+ arg.dst,
+ ast::FnArgumentType::Reg(ast::VariableRegType::Scalar(typ.into())),
+ )],
+ param_list: vec![
+ (
+ arg.src1,
+ ast::FnArgumentType::Reg(ast::VariableRegType::Scalar(typ.into())),
+ ),
+ (
+ arg.src2,
+ ast::FnArgumentType::Reg(ast::VariableRegType::Scalar(ast::ScalarType::U32)),
+ ),
+ (
+ arg.src3,
+ ast::FnArgumentType::Reg(ast::VariableRegType::Scalar(ast::ScalarType::U32)),
+ ),
+ ],
+ })
+}
+
+fn to_resolved_fn_args<T>(
+ params: Vec<T>,
+ params_decl: &[ast::FnArgumentType],
+) -> Vec<(T, ast::FnArgumentType)> {
+ params
+ .into_iter()
+ .zip(params_decl.iter())
+ .map(|(id, typ)| (id, typ.clone()))
+ .collect::<Vec<_>>()
+}
+
+fn normalize_labels(
+ func: Vec<ExpandedStatement>,
+ id_def: &mut NumericIdResolver,
+) -> Vec<ExpandedStatement> {
+ let mut labels_in_use = HashSet::new();
+ for s in func.iter() {
+ match s {
+ Statement::Instruction(i) => {
+ if let Some(target) = i.jump_target() {
+ labels_in_use.insert(target);
+ }
+ }
+ Statement::Conditional(cond) => {
+ labels_in_use.insert(cond.if_true);
+ labels_in_use.insert(cond.if_false);
+ }
+ Statement::Call(..)
+ | Statement::Variable(..)
+ | Statement::LoadVar(..)
+ | Statement::StoreVar(..)
+ | Statement::RetValue(..)
+ | Statement::Conversion(..)
+ | Statement::Constant(..)
+ | Statement::Label(..)
+ | Statement::PtrAccess { .. }
+ | Statement::RepackVector(..) => {}
+ }
+ }
+ iter::once(Statement::Label(id_def.new_non_variable(None)))
+ .chain(func.into_iter().filter(|s| match s {
+ Statement::Label(i) => labels_in_use.contains(i),
+ _ => true,
+ }))
+ .collect::<Vec<_>>()
+}
+
+fn normalize_predicates(
+ func: Vec<NormalizedStatement>,
+ id_def: &mut NumericIdResolver,
+) -> Result<Vec<UnconditionalStatement>, TranslateError> {
+ let mut result = Vec::with_capacity(func.len());
+ for s in func {
+ match s {
+ Statement::Label(id) => result.push(Statement::Label(id)),
+ Statement::Instruction((pred, inst)) => {
+ if let Some(pred) = pred {
+ let if_true = id_def.new_non_variable(None);
+ let if_false = id_def.new_non_variable(None);
+ let folded_bra = match &inst {
+ ast::Instruction::Bra(_, arg) => Some(arg.src),
+ _ => None,
+ };
+ let mut branch = BrachCondition {
+ predicate: pred.label,
+ if_true: folded_bra.unwrap_or(if_true),
+ if_false,
+ };
+ if pred.not {
+ std::mem::swap(&mut branch.if_true, &mut branch.if_false);
+ }
+ result.push(Statement::Conditional(branch));
+ if folded_bra.is_none() {
+ result.push(Statement::Label(if_true));
+ result.push(Statement::Instruction(inst));
+ }
+ result.push(Statement::Label(if_false));
+ } else {
+ result.push(Statement::Instruction(inst));
+ }
+ }
+ Statement::Variable(var) => result.push(Statement::Variable(var)),
+ // Blocks are flattened when resolving ids
+ _ => return Err(error_unreachable()),
+ }
+ }
+ Ok(result)
+}
+
+fn insert_mem_ssa_statements<'a, 'b>(
+ func: Vec<TypedStatement>,
+ id_def: &mut NumericIdResolver,
+ ast_fn_decl: &'a ast::MethodDecl<'b, spirv::Word>,
+ fn_decl: &mut SpirvMethodDecl,
+) -> Result<Vec<TypedStatement>, TranslateError> {
+ let is_func = match ast_fn_decl {
+ ast::MethodDecl::Func(..) => true,
+ ast::MethodDecl::Kernel { .. } => false,
+ };
+ let mut result = Vec::with_capacity(func.len());
+ for arg in fn_decl.output.iter() {
+ match type_to_variable_type(&arg.v_type, is_func)? {
+ Some(var_type) => {
+ result.push(Statement::Variable(ast::Variable {
+ align: arg.align,
+ v_type: var_type,
+ name: arg.name,
+ array_init: arg.array_init.clone(),
+ }));
+ }
+ None => return Err(error_unreachable()),
+ }
+ }
+ for spirv_arg in fn_decl.input.iter_mut() {
+ match type_to_variable_type(&spirv_arg.v_type, is_func)? {
+ Some(var_type) => {
+ let typ = spirv_arg.v_type.clone();
+ let new_id = id_def.new_non_variable(Some(typ.clone()));
+ result.push(Statement::Variable(ast::Variable {
+ align: spirv_arg.align,
+ v_type: var_type,
+ name: spirv_arg.name,
+ array_init: spirv_arg.array_init.clone(),
+ }));
+ result.push(Statement::StoreVar(StoreVarDetails {
+ arg: ast::Arg2St {
+ src1: spirv_arg.name,
+ src2: new_id,
+ },
+ typ,
+ member_index: None,
+ }));
+ spirv_arg.name = new_id;
+ }
+ None => {}
+ }
+ }
+ for s in func {
+ match s {
+ Statement::Call(call) => {
+ insert_mem_ssa_statement_default(id_def, &mut result, call.cast())?
+ }
+ Statement::Instruction(inst) => match inst {
+ ast::Instruction::Ret(d) => {
+ // TODO: handle multiple output args
+ if let &[out_param] = &fn_decl.output.as_slice() {
+ let (typ, _) = id_def.get_typed(out_param.name)?;
+ let new_id = id_def.new_non_variable(Some(typ.clone()));
+ result.push(Statement::LoadVar(LoadVarDetails {
+ arg: ast::Arg2 {
+ dst: new_id,
+ src: out_param.name,
+ },
+ typ: typ.clone(),
+ member_index: None,
+ }));
+ result.push(Statement::RetValue(d, new_id));
+ } else {
+ result.push(Statement::Instruction(ast::Instruction::Ret(d)))
+ }
+ }
+ inst => insert_mem_ssa_statement_default(id_def, &mut result, inst)?,
+ },
+ Statement::Conditional(mut bra) => {
+ let generated_id =
+ id_def.new_non_variable(Some(ast::Type::Scalar(ast::ScalarType::Pred)));
+ result.push(Statement::LoadVar(LoadVarDetails {
+ arg: Arg2 {
+ dst: generated_id,
+ src: bra.predicate,
+ },
+ typ: ast::Type::Scalar(ast::ScalarType::Pred),
+ member_index: None,
+ }));
+ bra.predicate = generated_id;
+ result.push(Statement::Conditional(bra));
+ }
+ Statement::Conversion(conv) => {
+ insert_mem_ssa_statement_default(id_def, &mut result, conv)?
+ }
+ Statement::PtrAccess(ptr_access) => {
+ insert_mem_ssa_statement_default(id_def, &mut result, ptr_access)?
+ }
+ Statement::RepackVector(repack) => {
+ insert_mem_ssa_statement_default(id_def, &mut result, repack)?
+ }
+ s @ Statement::Variable(_) | s @ Statement::Label(_) => result.push(s),
+ _ => return Err(error_unreachable()),
+ }
+ }
+ Ok(result)
+}
+
+fn type_to_variable_type(
+ t: &ast::Type,
+ is_func: bool,
+) -> Result<Option<ast::VariableType>, TranslateError> {
+ Ok(match t {
+ ast::Type::Scalar(typ) => Some(ast::VariableType::Reg(ast::VariableRegType::Scalar(*typ))),
+ ast::Type::Vector(typ, len) => Some(ast::VariableType::Reg(ast::VariableRegType::Vector(
+ (*typ)
+ .try_into()
+ .map_err(|_| TranslateError::MismatchedType)?,
+ *len,
+ ))),
+ ast::Type::Array(typ, len) => Some(ast::VariableType::Reg(ast::VariableRegType::Array(
+ (*typ)
+ .try_into()
+ .map_err(|_| TranslateError::MismatchedType)?,
+ len.clone(),
+ ))),
+ ast::Type::Pointer(ast::PointerType::Scalar(scalar_type), space) => {
+ if is_func {
+ return Ok(None);
+ }
+ Some(ast::VariableType::Reg(ast::VariableRegType::Pointer(
+ scalar_type
+ .clone()
+ .try_into()
+ .map_err(|_| error_unreachable())?,
+ (*space).try_into().map_err(|_| error_unreachable())?,
+ )))
+ }
+ ast::Type::Pointer(_, ast::LdStateSpace::Shared) => None,
+ _ => return Err(error_unreachable()),
+ })
+}
+
+trait Visitable<From: ArgParamsEx, To: ArgParamsEx>: Sized {
+ fn visit(
+ self,
+ visitor: &mut impl ArgumentMapVisitor<From, To>,
+ ) -> Result<Statement<ast::Instruction<To>, To>, TranslateError>;
+}
+
+struct VisitArgumentDescriptor<
+ 'a,
+ Ctor: FnOnce(spirv::Word) -> Statement<ast::Instruction<U>, U>,
+ U: ArgParamsEx,
+> {
+ desc: ArgumentDescriptor<spirv::Word>,
+ typ: &'a ast::Type,
+ stmt_ctor: Ctor,
+}
+
+impl<
+ 'a,
+ Ctor: FnOnce(spirv::Word) -> Statement<ast::Instruction<U>, U>,
+ T: ArgParamsEx<Id = spirv::Word>,
+ U: ArgParamsEx<Id = spirv::Word>,
+ > Visitable<T, U> for VisitArgumentDescriptor<'a, Ctor, U>
+{
+ fn visit(
+ self,
+ visitor: &mut impl ArgumentMapVisitor<T, U>,
+ ) -> Result<Statement<ast::Instruction<U>, U>, TranslateError> {
+ Ok((self.stmt_ctor)(visitor.id(self.desc, Some(self.typ))?))
+ }
+}
+
+struct InsertMemSSAVisitor<'a, 'input> {
+ id_def: &'a mut NumericIdResolver<'input>,
+ func: &'a mut Vec<TypedStatement>,
+ post_statements: Vec<TypedStatement>,
+}
+
+impl<'a, 'input> InsertMemSSAVisitor<'a, 'input> {
+ fn symbol(
+ &mut self,
+ desc: ArgumentDescriptor<(spirv::Word, Option<u8>)>,
+ expected_type: Option<&ast::Type>,
+ ) -> Result<spirv::Word, TranslateError> {
+ let symbol = desc.op.0;
+ if expected_type.is_none() {
+ return Ok(symbol);
+ };
+ let (mut var_type, is_variable) = self.id_def.get_typed(symbol)?;
+ if !is_variable {
+ return Ok(symbol);
+ };
+ let member_index = match desc.op.1 {
+ Some(idx) => {
+ let vector_width = match var_type {
+ ast::Type::Vector(scalar_t, width) => {
+ var_type = ast::Type::Scalar(scalar_t);
+ width
+ }
+ _ => return Err(TranslateError::MismatchedType),
+ };
+ Some((
+ idx,
+ if self.id_def.special_registers.get(symbol).is_some() {
+ Some(vector_width)
+ } else {
+ None
+ },
+ ))
+ }
+ None => None,
+ };
+ let generated_id = self.id_def.new_non_variable(Some(var_type.clone()));
+ if !desc.is_dst {
+ self.func.push(Statement::LoadVar(LoadVarDetails {
+ arg: Arg2 {
+ dst: generated_id,
+ src: symbol,
+ },
+ typ: var_type,
+ member_index,
+ }));
+ } else {
+ self.post_statements
+ .push(Statement::StoreVar(StoreVarDetails {
+ arg: Arg2St {
+ src1: symbol,
+ src2: generated_id,
+ },
+ typ: var_type,
+ member_index: member_index.map(|(idx, _)| idx),
+ }));
+ }
+ Ok(generated_id)
+ }
+}
+
+impl<'a, 'input> ArgumentMapVisitor<TypedArgParams, TypedArgParams>
+ for InsertMemSSAVisitor<'a, 'input>
+{
+ fn id(
+ &mut self,
+ desc: ArgumentDescriptor<spirv::Word>,
+ typ: Option<&ast::Type>,
+ ) -> Result<spirv::Word, TranslateError> {
+ self.symbol(desc.new_op((desc.op, None)), typ)
+ }
+
+ fn operand(
+ &mut self,
+ desc: ArgumentDescriptor<TypedOperand>,
+ typ: &ast::Type,
+ ) -> Result<TypedOperand, TranslateError> {
+ Ok(match desc.op {
+ TypedOperand::Reg(reg) => {
+ TypedOperand::Reg(self.symbol(desc.new_op((reg, None)), Some(typ))?)
+ }
+ TypedOperand::RegOffset(reg, offset) => {
+ TypedOperand::RegOffset(self.symbol(desc.new_op((reg, None)), Some(typ))?, offset)
+ }
+ op @ TypedOperand::Imm(..) => op,
+ TypedOperand::VecMember(symbol, index) => {
+ TypedOperand::Reg(self.symbol(desc.new_op((symbol, Some(index))), Some(typ))?)
+ }
+ })
+ }
+}
+
+fn insert_mem_ssa_statement_default<'a, 'input, S: Visitable<TypedArgParams, TypedArgParams>>(
+ id_def: &'a mut NumericIdResolver<'input>,
+ func: &'a mut Vec<TypedStatement>,
+ stmt: S,
+) -> Result<(), TranslateError> {
+ let mut visitor = InsertMemSSAVisitor {
+ id_def,
+ func,
+ post_statements: Vec::new(),
+ };
+ let new_stmt = stmt.visit(&mut visitor)?;
+ visitor.func.push(new_stmt);
+ visitor.func.extend(visitor.post_statements);
+ Ok(())
+}
+
+fn expand_arguments<'a, 'b>(
+ func: Vec<TypedStatement>,
+ id_def: &'b mut MutableNumericIdResolver<'a>,
+) -> Result<Vec<ExpandedStatement>, TranslateError> {
+ let mut result = Vec::with_capacity(func.len());
+ for s in func {
+ match s {
+ Statement::Call(call) => {
+ let mut visitor = FlattenArguments::new(&mut result, id_def);
+ let (new_call, post_stmts) = (call.map(&mut visitor)?, visitor.post_stmts);
+ result.push(Statement::Call(new_call));
+ result.extend(post_stmts);
+ }
+ Statement::Instruction(inst) => {
+ let mut visitor = FlattenArguments::new(&mut result, id_def);
+ let (new_inst, post_stmts) = (inst.map(&mut visitor)?, visitor.post_stmts);
+ result.push(Statement::Instruction(new_inst));
+ result.extend(post_stmts);
+ }
+ Statement::Variable(ast::Variable {
+ align,
+ v_type,
+ name,
+ array_init,
+ }) => result.push(Statement::Variable(ast::Variable {
+ align,
+ v_type,
+ name,
+ array_init,
+ })),
+ Statement::PtrAccess(ptr_access) => {
+ let mut visitor = FlattenArguments::new(&mut result, id_def);
+ let (new_inst, post_stmts) = (ptr_access.map(&mut visitor)?, visitor.post_stmts);
+ result.push(Statement::PtrAccess(new_inst));
+ result.extend(post_stmts);
+ }
+ Statement::RepackVector(repack) => {
+ let mut visitor = FlattenArguments::new(&mut result, id_def);
+ let (new_inst, post_stmts) = (repack.map(&mut visitor)?, visitor.post_stmts);
+ result.push(Statement::RepackVector(new_inst));
+ result.extend(post_stmts);
+ }
+ Statement::Label(id) => result.push(Statement::Label(id)),
+ Statement::Conditional(bra) => result.push(Statement::Conditional(bra)),
+ Statement::LoadVar(details) => result.push(Statement::LoadVar(details)),
+ Statement::StoreVar(details) => result.push(Statement::StoreVar(details)),
+ Statement::RetValue(d, id) => result.push(Statement::RetValue(d, id)),
+ Statement::Conversion(conv) => result.push(Statement::Conversion(conv)),
+ Statement::Constant(_) => return Err(error_unreachable()),
+ }
+ }
+ Ok(result)
+}
+
+struct FlattenArguments<'a, 'b> {
+ func: &'b mut Vec<ExpandedStatement>,
+ id_def: &'b mut MutableNumericIdResolver<'a>,
+ post_stmts: Vec<ExpandedStatement>,
+}
+
+impl<'a, 'b> FlattenArguments<'a, 'b> {
+ fn new(
+ func: &'b mut Vec<ExpandedStatement>,
+ id_def: &'b mut MutableNumericIdResolver<'a>,
+ ) -> Self {
+ FlattenArguments {
+ func,
+ id_def,
+ post_stmts: Vec::new(),
+ }
+ }
+
+ fn reg(
+ &mut self,
+ desc: ArgumentDescriptor<spirv::Word>,
+ _: Option<&ast::Type>,
+ ) -> Result<spirv::Word, TranslateError> {
+ Ok(desc.op)
+ }
+
+ fn reg_offset(
+ &mut self,
+ desc: ArgumentDescriptor<(spirv::Word, i32)>,
+ typ: &ast::Type,
+ ) -> Result<spirv::Word, TranslateError> {
+ let (reg, offset) = desc.op;
+ let add_type;
+ match typ {
+ ast::Type::Pointer(underlying_type, state_space) => {
+ let reg_typ = self.id_def.get_typed(reg)?;
+ if let ast::Type::Pointer(_, _) = reg_typ {
+ let id_constant_stmt = self.id_def.new_non_variable(typ.clone());
+ self.func.push(Statement::Constant(ConstantDefinition {
+ dst: id_constant_stmt,
+ typ: ast::ScalarType::S64,
+ value: ast::ImmediateValue::S64(offset as i64),
+ }));
+ let dst = self.id_def.new_non_variable(typ.clone());
+ self.func.push(Statement::PtrAccess(PtrAccess {
+ underlying_type: underlying_type.clone(),
+ state_space: *state_space,
+ dst,
+ ptr_src: reg,
+ offset_src: id_constant_stmt,
+ }));
+ return Ok(dst);
+ } else {
+ add_type = self.id_def.get_typed(reg)?;
+ }
+ }
+ _ => {
+ add_type = typ.clone();
+ }
+ };
+ let (width, kind) = match add_type {
+ ast::Type::Scalar(scalar_t) => {
+ let kind = match scalar_t.kind() {
+ kind @ ScalarKind::Bit
+ | kind @ ScalarKind::Unsigned
+ | kind @ ScalarKind::Signed => kind,
+ ScalarKind::Float => return Err(TranslateError::MismatchedType),
+ ScalarKind::Float2 => return Err(TranslateError::MismatchedType),
+ ScalarKind::Pred => return Err(TranslateError::MismatchedType),
+ };
+ (scalar_t.size_of(), kind)
+ }
+ _ => return Err(TranslateError::MismatchedType),
+ };
+ let arith_detail = if kind == ScalarKind::Signed {
+ ast::ArithDetails::Signed(ast::ArithSInt {
+ typ: ast::SIntType::from_size(width),
+ saturate: false,
+ })
+ } else {
+ ast::ArithDetails::Unsigned(ast::UIntType::from_size(width))
+ };
+ let id_constant_stmt = self.id_def.new_non_variable(add_type.clone());
+ let result_id = self.id_def.new_non_variable(add_type);
+ // TODO: check for edge cases around min value/max value/wrapping
+ if offset < 0 && kind != ScalarKind::Signed {
+ self.func.push(Statement::Constant(ConstantDefinition {
+ dst: id_constant_stmt,
+ typ: ast::ScalarType::from_parts(width, kind),
+ value: ast::ImmediateValue::U64(-(offset as i64) as u64),
+ }));
+ self.func.push(Statement::Instruction(
+ ast::Instruction::<ExpandedArgParams>::Sub(
+ arith_detail,
+ ast::Arg3 {
+ dst: result_id,
+ src1: reg,
+ src2: id_constant_stmt,
+ },
+ ),
+ ));
+ } else {
+ self.func.push(Statement::Constant(ConstantDefinition {
+ dst: id_constant_stmt,
+ typ: ast::ScalarType::from_parts(width, kind),
+ value: ast::ImmediateValue::S64(offset as i64),
+ }));
+ self.func.push(Statement::Instruction(
+ ast::Instruction::<ExpandedArgParams>::Add(
+ arith_detail,
+ ast::Arg3 {
+ dst: result_id,
+ src1: reg,
+ src2: id_constant_stmt,
+ },
+ ),
+ ));
+ }
+ Ok(result_id)
+ }
+
+ fn immediate(
+ &mut self,
+ desc: ArgumentDescriptor<ast::ImmediateValue>,
+ typ: &ast::Type,
+ ) -> Result<spirv::Word, TranslateError> {
+ let scalar_t = if let ast::Type::Scalar(scalar) = typ {
+ *scalar
+ } else {
+ todo!()
+ };
+ let id = self.id_def.new_non_variable(ast::Type::Scalar(scalar_t));
+ self.func.push(Statement::Constant(ConstantDefinition {
+ dst: id,
+ typ: scalar_t,
+ value: desc.op,
+ }));
+ Ok(id)
+ }
+}
+
+impl<'a, 'b> ArgumentMapVisitor<TypedArgParams, ExpandedArgParams> for FlattenArguments<'a, 'b> {
+ fn id(
+ &mut self,
+ desc: ArgumentDescriptor<spirv::Word>,
+ t: Option<&ast::Type>,
+ ) -> Result<spirv::Word, TranslateError> {
+ self.reg(desc, t)
+ }
+
+ fn operand(
+ &mut self,
+ desc: ArgumentDescriptor<TypedOperand>,
+ typ: &ast::Type,
+ ) -> Result<spirv::Word, TranslateError> {
+ match desc.op {
+ TypedOperand::Reg(r) => self.reg(desc.new_op(r), Some(typ)),
+ TypedOperand::Imm(x) => self.immediate(desc.new_op(x), typ),
+ TypedOperand::RegOffset(reg, offset) => {
+ self.reg_offset(desc.new_op((reg, offset)), typ)
+ }
+ TypedOperand::VecMember(..) => Err(error_unreachable()),
+ }
+ }
+}
+
+/*
+ There are several kinds of implicit conversions in PTX:
+ * auto-bitcast: https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#type-information-for-instructions-and-operands
+ * special ld/st/cvt conversion rules: https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#operand-size-exceeding-instruction-type-size
+ - ld.param: not documented, but for instruction `ld.param.<type> x, [y]`,
+ semantics are to first zext/chop/bitcast `y` as needed and then do
+ documented special ld/st/cvt conversion rules for destination operands
+ - st.param [x] y (used as function return arguments) same rule as above applies
+ - generic/global ld: for instruction `ld x, [y]`, y must be of type
+ b64/u64/s64, which is bitcast to a pointer, dereferenced and then
+ documented special ld/st/cvt conversion rules are applied to dst
+ - generic/global st: for instruction `st [x], y`, x must be of type
+ b64/u64/s64, which is bitcast to a pointer
+*/
+fn insert_implicit_conversions(
+ func: Vec<ExpandedStatement>,
+ id_def: &mut MutableNumericIdResolver,
+) -> Result<Vec<ExpandedStatement>, TranslateError> {
+ let mut result = Vec::with_capacity(func.len());
+ for s in func.into_iter() {
+ match s {
+ Statement::Call(call) => insert_implicit_conversions_impl(
+ &mut result,
+ id_def,
+ call,
+ should_bitcast_wrapper,
+ None,
+ )?,
+ Statement::Instruction(inst) => {
+ let mut default_conversion_fn =
+ should_bitcast_wrapper as for<'a> fn(&'a ast::Type, &'a ast::Type, _) -> _;
+ let mut state_space = None;
+ if let ast::Instruction::Ld(d, _) = &inst {
+ state_space = Some(d.state_space);
+ }
+ if let ast::Instruction::St(d, _) = &inst {
+ state_space = Some(d.state_space.to_ld_ss());
+ }
+ if let ast::Instruction::Atom(d, _) = &inst {
+ state_space = Some(d.space.to_ld_ss());
+ }
+ if let ast::Instruction::AtomCas(d, _) = &inst {
+ state_space = Some(d.space.to_ld_ss());
+ }
+ if let ast::Instruction::Mov(..) = &inst {
+ default_conversion_fn = should_bitcast_packed;
+ }
+ insert_implicit_conversions_impl(
+ &mut result,
+ id_def,
+ inst,
+ default_conversion_fn,
+ state_space,
+ )?;
+ }
+ Statement::PtrAccess(PtrAccess {
+ underlying_type,
+ state_space,
+ dst,
+ ptr_src,
+ offset_src: constant_src,
+ }) => {
+ let visit_desc = VisitArgumentDescriptor {
+ desc: ArgumentDescriptor {
+ op: ptr_src,
+ is_dst: false,
+ sema: ArgumentSemantics::PhysicalPointer,
+ },
+ typ: &ast::Type::Pointer(underlying_type.clone(), state_space),
+ stmt_ctor: |new_ptr_src| {
+ Statement::PtrAccess(PtrAccess {
+ underlying_type,
+ state_space,
+ dst,
+ ptr_src: new_ptr_src,
+ offset_src: constant_src,
+ })
+ },
+ };
+ insert_implicit_conversions_impl(
+ &mut result,
+ id_def,
+ visit_desc,
+ bitcast_physical_pointer,
+ Some(state_space),
+ )?;
+ }
+ Statement::RepackVector(repack) => insert_implicit_conversions_impl(
+ &mut result,
+ id_def,
+ repack,
+ should_bitcast_wrapper,
+ None,
+ )?,
+ s @ Statement::Conditional(_)
+ | s @ Statement::Conversion(_)
+ | s @ Statement::Label(_)
+ | s @ Statement::Constant(_)
+ | s @ Statement::Variable(_)
+ | s @ Statement::LoadVar(..)
+ | s @ Statement::StoreVar(..)
+ | s @ Statement::RetValue(_, _) => result.push(s),
+ }
+ }
+ Ok(result)
+}
+
+fn insert_implicit_conversions_impl(
+ func: &mut Vec<ExpandedStatement>,
+ id_def: &mut MutableNumericIdResolver,
+ stmt: impl Visitable<ExpandedArgParams, ExpandedArgParams>,
+ default_conversion_fn: for<'a> fn(
+ &'a ast::Type,
+ &'a ast::Type,
+ Option<ast::LdStateSpace>,
+ ) -> Result<Option<ConversionKind>, TranslateError>,
+ state_space: Option<ast::LdStateSpace>,
+) -> Result<(), TranslateError> {
+ let mut post_conv = Vec::new();
+ let statement = stmt.visit(
+ &mut |desc: ArgumentDescriptor<spirv::Word>, typ: Option<&ast::Type>| {
+ let instr_type = match typ {
+ None => return Ok(desc.op),
+ Some(t) => t,
+ };
+ let operand_type = id_def.get_typed(desc.op)?;
+ let mut conversion_fn = default_conversion_fn;
+ match desc.sema {
+ ArgumentSemantics::Default => {}
+ ArgumentSemantics::DefaultRelaxed => {
+ if desc.is_dst {
+ conversion_fn = should_convert_relaxed_dst_wrapper;
+ } else {
+ conversion_fn = should_convert_relaxed_src_wrapper;
+ }
+ }
+ ArgumentSemantics::PhysicalPointer => {
+ conversion_fn = bitcast_physical_pointer;
+ }
+ ArgumentSemantics::RegisterPointer => {
+ conversion_fn = bitcast_register_pointer;
+ }
+ ArgumentSemantics::Address => {
+ conversion_fn = force_bitcast_ptr_to_bit;
+ }
+ };
+ match conversion_fn(&operand_type, instr_type, state_space)? {
+ Some(conv_kind) => {
+ let conv_output = if desc.is_dst {
+ &mut post_conv
+ } else {
+ &mut *func
+ };
+ let mut from = instr_type.clone();
+ let mut to = operand_type;
+ let mut src = id_def.new_non_variable(instr_type.clone());
+ let mut dst = desc.op;
+ let result = Ok(src);
+ if !desc.is_dst {
+ mem::swap(&mut src, &mut dst);
+ mem::swap(&mut from, &mut to);
+ }
+ conv_output.push(Statement::Conversion(ImplicitConversion {
+ src,
+ dst,
+ from,
+ to,
+ kind: conv_kind,
+ src_sema: ArgumentSemantics::Default,
+ dst_sema: ArgumentSemantics::Default,
+ }));
+ result
+ }
+ None => Ok(desc.op),
+ }
+ },
+ )?;
+ func.push(statement);
+ func.append(&mut post_conv);
+ Ok(())
+}
+
+fn get_function_type(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ spirv_input: &[ast::Variable<ast::Type, spirv::Word>],
+ spirv_output: &[ast::Variable<ast::Type, spirv::Word>],
+) -> (spirv::Word, spirv::Word) {
+ map.get_or_add_fn(
+ builder,
+ spirv_input
+ .iter()
+ .map(|var| SpirvType::from(var.v_type.clone())),
+ spirv_output
+ .iter()
+ .map(|var| SpirvType::from(var.v_type.clone())),
+ )
+}
+
+fn emit_function_body_ops(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ opencl: spirv::Word,
+ func: &[ExpandedStatement],
+) -> Result<(), TranslateError> {
+ for s in func {
+ match s {
+ Statement::Label(id) => {
+ if builder.block.is_some() {
+ builder.branch(*id)?;
+ }
+ builder.begin_block(Some(*id))?;
+ }
+ _ => {
+ if builder.block.is_none() && builder.function.is_some() {
+ builder.begin_block(None)?;
+ }
+ }
+ }
+ match s {
+ Statement::Label(_) => (),
+ Statement::Call(call) => {
+ let (result_type, result_id) = match &*call.ret_params {
+ [(id, typ)] => (
+ map.get_or_add(builder, SpirvType::from(typ.to_func_type())),
+ Some(*id),
+ ),
+ [] => (map.void(), None),
+ _ => todo!(),
+ };
+ let arg_list = call
+ .param_list
+ .iter()
+ .map(|(id, _)| *id)
+ .collect::<Vec<_>>();
+ builder.function_call(result_type, result_id, call.func, arg_list)?;
+ }
+ Statement::Variable(var) => {
+ emit_variable(builder, map, var)?;
+ }
+ Statement::Constant(cnst) => {
+ let typ_id = map.get_or_add_scalar(builder, cnst.typ);
+ match (cnst.typ, cnst.value) {
+ (ast::ScalarType::B8, ast::ImmediateValue::U64(value))
+ | (ast::ScalarType::U8, ast::ImmediateValue::U64(value)) => {
+ builder.constant_u32(typ_id, Some(cnst.dst), value as u8 as u32);
+ }
+ (ast::ScalarType::B16, ast::ImmediateValue::U64(value))
+ | (ast::ScalarType::U16, ast::ImmediateValue::U64(value)) => {
+ builder.constant_u32(typ_id, Some(cnst.dst), value as u16 as u32);
+ }
+ (ast::ScalarType::B32, ast::ImmediateValue::U64(value))
+ | (ast::ScalarType::U32, ast::ImmediateValue::U64(value)) => {
+ builder.constant_u32(typ_id, Some(cnst.dst), value as u32);
+ }
+ (ast::ScalarType::B64, ast::ImmediateValue::U64(value))
+ | (ast::ScalarType::U64, ast::ImmediateValue::U64(value)) => {
+ builder.constant_u64(typ_id, Some(cnst.dst), value);
+ }
+ (ast::ScalarType::S8, ast::ImmediateValue::U64(value)) => {
+ builder.constant_u32(typ_id, Some(cnst.dst), value as i8 as u32);
+ }
+ (ast::ScalarType::S16, ast::ImmediateValue::U64(value)) => {
+ builder.constant_u32(typ_id, Some(cnst.dst), value as i16 as u32);
+ }
+ (ast::ScalarType::S32, ast::ImmediateValue::U64(value)) => {
+ builder.constant_u32(typ_id, Some(cnst.dst), value as i32 as u32);
+ }
+ (ast::ScalarType::S64, ast::ImmediateValue::U64(value)) => {
+ builder.constant_u64(typ_id, Some(cnst.dst), value as i64 as u64);
+ }
+ (ast::ScalarType::B8, ast::ImmediateValue::S64(value))
+ | (ast::ScalarType::U8, ast::ImmediateValue::S64(value)) => {
+ builder.constant_u32(typ_id, Some(cnst.dst), value as u8 as u32);
+ }
+ (ast::ScalarType::B16, ast::ImmediateValue::S64(value))
+ | (ast::ScalarType::U16, ast::ImmediateValue::S64(value)) => {
+ builder.constant_u32(typ_id, Some(cnst.dst), value as u16 as u32);
+ }
+ (ast::ScalarType::B32, ast::ImmediateValue::S64(value))
+ | (ast::ScalarType::U32, ast::ImmediateValue::S64(value)) => {
+ builder.constant_u32(typ_id, Some(cnst.dst), value as u32);
+ }
+ (ast::ScalarType::B64, ast::ImmediateValue::S64(value))
+ | (ast::ScalarType::U64, ast::ImmediateValue::S64(value)) => {
+ builder.constant_u64(typ_id, Some(cnst.dst), value as u64);
+ }
+ (ast::ScalarType::S8, ast::ImmediateValue::S64(value)) => {
+ builder.constant_u32(typ_id, Some(cnst.dst), value as i8 as u32);
+ }
+ (ast::ScalarType::S16, ast::ImmediateValue::S64(value)) => {
+ builder.constant_u32(typ_id, Some(cnst.dst), value as i16 as u32);
+ }
+ (ast::ScalarType::S32, ast::ImmediateValue::S64(value)) => {
+ builder.constant_u32(typ_id, Some(cnst.dst), value as i32 as u32);
+ }
+ (ast::ScalarType::S64, ast::ImmediateValue::S64(value)) => {
+ builder.constant_u64(typ_id, Some(cnst.dst), value as u64);
+ }
+ (ast::ScalarType::F16, ast::ImmediateValue::F32(value)) => {
+ builder.constant_f32(typ_id, Some(cnst.dst), f16::from_f32(value).to_f32());
+ }
+ (ast::ScalarType::F32, ast::ImmediateValue::F32(value)) => {
+ builder.constant_f32(typ_id, Some(cnst.dst), value);
+ }
+ (ast::ScalarType::F64, ast::ImmediateValue::F32(value)) => {
+ builder.constant_f64(typ_id, Some(cnst.dst), value as f64);
+ }
+ (ast::ScalarType::F16, ast::ImmediateValue::F64(value)) => {
+ builder.constant_f32(typ_id, Some(cnst.dst), f16::from_f64(value).to_f32());
+ }
+ (ast::ScalarType::F32, ast::ImmediateValue::F64(value)) => {
+ builder.constant_f32(typ_id, Some(cnst.dst), value as f32);
+ }
+ (ast::ScalarType::F64, ast::ImmediateValue::F64(value)) => {
+ builder.constant_f64(typ_id, Some(cnst.dst), value);
+ }
+ (ast::ScalarType::Pred, ast::ImmediateValue::U64(value)) => {
+ let bool_type = map.get_or_add_scalar(builder, ast::ScalarType::Pred);
+ if value == 0 {
+ builder.constant_false(bool_type, Some(cnst.dst));
+ } else {
+ builder.constant_true(bool_type, Some(cnst.dst));
+ }
+ }
+ (ast::ScalarType::Pred, ast::ImmediateValue::S64(value)) => {
+ let bool_type = map.get_or_add_scalar(builder, ast::ScalarType::Pred);
+ if value == 0 {
+ builder.constant_false(bool_type, Some(cnst.dst));
+ } else {
+ builder.constant_true(bool_type, Some(cnst.dst));
+ }
+ }
+ _ => return Err(TranslateError::MismatchedType),
+ }
+ }
+ Statement::Conversion(cv) => emit_implicit_conversion(builder, map, cv)?,
+ Statement::Conditional(bra) => {
+ builder.branch_conditional(bra.predicate, bra.if_true, bra.if_false, [])?;
+ }
+ Statement::Instruction(inst) => match inst {
+ ast::Instruction::Abs(d, arg) => emit_abs(builder, map, opencl, d, arg)?,
+ ast::Instruction::Call(_) => unreachable!(),
+ // SPIR-V does not support marking jumps as guaranteed-converged
+ ast::Instruction::Bra(_, arg) => {
+ builder.branch(arg.src)?;
+ }
+ ast::Instruction::Ld(data, arg) => {
+ if data.qualifier != ast::LdStQualifier::Weak {
+ todo!()
+ }
+ let result_type =
+ map.get_or_add(builder, SpirvType::from(ast::Type::from(data.typ.clone())));
+ builder.load(
+ result_type,
+ Some(arg.dst),
+ arg.src,
+ Some(spirv::MemoryAccess::ALIGNED),
+ [dr::Operand::LiteralInt32(
+ ast::Type::from(data.typ.clone()).size_of() as u32,
+ )],
+ )?;
+ }
+ ast::Instruction::St(data, arg) => {
+ if data.qualifier != ast::LdStQualifier::Weak {
+ todo!()
+ }
+ builder.store(
+ arg.src1,
+ arg.src2,
+ Some(spirv::MemoryAccess::ALIGNED),
+ [dr::Operand::LiteralInt32(
+ ast::Type::from(data.typ.clone()).size_of() as u32,
+ )],
+ )?;
+ }
+ // SPIR-V does not support ret as guaranteed-converged
+ ast::Instruction::Ret(_) => builder.ret()?,
+ ast::Instruction::Mov(d, arg) => {
+ let result_type =
+ map.get_or_add(builder, SpirvType::from(ast::Type::from(d.typ.clone())));
+ builder.copy_object(result_type, Some(arg.dst), arg.src)?;
+ }
+ ast::Instruction::Mul(mul, arg) => match mul {
+ ast::MulDetails::Signed(ref ctr) => {
+ emit_mul_sint(builder, map, opencl, ctr, arg)?
+ }
+ ast::MulDetails::Unsigned(ref ctr) => {
+ emit_mul_uint(builder, map, opencl, ctr, arg)?
+ }
+ ast::MulDetails::Float(ref ctr) => emit_mul_float(builder, map, ctr, arg)?,
+ },
+ ast::Instruction::Add(add, arg) => match add {
+ ast::ArithDetails::Signed(ref desc) => {
+ emit_add_int(builder, map, desc.typ.into(), desc.saturate, arg)?
+ }
+ ast::ArithDetails::Unsigned(ref desc) => {
+ emit_add_int(builder, map, (*desc).into(), false, arg)?
+ }
+ ast::ArithDetails::Float(desc) => emit_add_float(builder, map, desc, arg)?,
+ },
+ ast::Instruction::Setp(setp, arg) => {
+ if arg.dst2.is_some() {
+ todo!()
+ }
+ emit_setp(builder, map, setp, arg)?;
+ }
+ ast::Instruction::Not(t, a) => {
+ let result_type = map.get_or_add(builder, SpirvType::from(t.to_type()));
+ let result_id = Some(a.dst);
+ let operand = a.src;
+ match t {
+ ast::BooleanType::Pred => {
+ // HACK ALERT
+ // Temporary workaround until IGC gets its shit together
+ // Currently IGC carries two copies of SPIRV-LLVM translator
+ // a new one in /llvm-spirv/ and old one in /IGC/AdaptorOCL/SPIRV/.
+ // Obviously, old and buggy one is used for compiling L0 SPIRV
+ // https://github.com/intel/intel-graphics-compiler/issues/148
+ let type_pred = map.get_or_add_scalar(builder, ast::ScalarType::Pred);
+ let const_true = builder.constant_true(type_pred, None);
+ let const_false = builder.constant_false(type_pred, None);
+ builder.select(result_type, result_id, operand, const_false, const_true)
+ }
+ _ => builder.not(result_type, result_id, operand),
+ }?;
+ }
+ ast::Instruction::Shl(t, a) => {
+ let full_type = t.to_type();
+ let size_of = full_type.size_of();
+ let result_type = map.get_or_add(builder, SpirvType::from(full_type));
+ let offset_src = insert_shift_hack(builder, map, a.src2, size_of)?;
+ builder.shift_left_logical(result_type, Some(a.dst), a.src1, offset_src)?;
+ }
+ ast::Instruction::Shr(t, a) => {
+ let full_type = ast::ScalarType::from(*t);
+ let size_of = full_type.size_of();
+ let result_type = map.get_or_add_scalar(builder, full_type);
+ let offset_src = insert_shift_hack(builder, map, a.src2, size_of as usize)?;
+ if t.signed() {
+ builder.shift_right_arithmetic(
+ result_type,
+ Some(a.dst),
+ a.src1,
+ offset_src,
+ )?;
+ } else {
+ builder.shift_right_logical(
+ result_type,
+ Some(a.dst),
+ a.src1,
+ offset_src,
+ )?;
+ }
+ }
+ ast::Instruction::Cvt(dets, arg) => {
+ emit_cvt(builder, map, opencl, dets, arg)?;
+ }
+ ast::Instruction::Cvta(_, arg) => {
+ // This would be only meaningful if const/slm/global pointers
+ // had a different format than generic pointers, but they don't pretty much by ptx definition
+ // Honestly, I have no idea why this instruction exists and is emitted by the compiler
+ let result_type = map.get_or_add_scalar(builder, ast::ScalarType::B64);
+ builder.copy_object(result_type, Some(arg.dst), arg.src)?;
+ }
+ ast::Instruction::SetpBool(_, _) => todo!(),
+ ast::Instruction::Mad(mad, arg) => match mad {
+ ast::MulDetails::Signed(ref desc) => {
+ emit_mad_sint(builder, map, opencl, desc, arg)?
+ }
+ ast::MulDetails::Unsigned(ref desc) => {
+ emit_mad_uint(builder, map, opencl, desc, arg)?
+ }
+ ast::MulDetails::Float(desc) => {
+ emit_mad_float(builder, map, opencl, desc, arg)?
+ }
+ },
+ ast::Instruction::Or(t, a) => {
+ let result_type = map.get_or_add_scalar(builder, ast::ScalarType::from(*t));
+ if *t == ast::BooleanType::Pred {
+ builder.logical_or(result_type, Some(a.dst), a.src1, a.src2)?;
+ } else {
+ builder.bitwise_or(result_type, Some(a.dst), a.src1, a.src2)?;
+ }
+ }
+ ast::Instruction::Sub(d, arg) => match d {
+ ast::ArithDetails::Signed(desc) => {
+ emit_sub_int(builder, map, desc.typ.into(), desc.saturate, arg)?;
+ }
+ ast::ArithDetails::Unsigned(desc) => {
+ emit_sub_int(builder, map, (*desc).into(), false, arg)?;
+ }
+ ast::ArithDetails::Float(desc) => {
+ emit_sub_float(builder, map, desc, arg)?;
+ }
+ },
+ ast::Instruction::Min(d, a) => {
+ emit_min(builder, map, opencl, d, a)?;
+ }
+ ast::Instruction::Max(d, a) => {
+ emit_max(builder, map, opencl, d, a)?;
+ }
+ ast::Instruction::Rcp(d, a) => {
+ emit_rcp(builder, map, d, a)?;
+ }
+ ast::Instruction::And(t, a) => {
+ let result_type = map.get_or_add_scalar(builder, ast::ScalarType::from(*t));
+ if *t == ast::BooleanType::Pred {
+ builder.logical_and(result_type, Some(a.dst), a.src1, a.src2)?;
+ } else {
+ builder.bitwise_and(result_type, Some(a.dst), a.src1, a.src2)?;
+ }
+ }
+ ast::Instruction::Selp(t, a) => {
+ let result_type = map.get_or_add_scalar(builder, ast::ScalarType::from(*t));
+ builder.select(result_type, Some(a.dst), a.src3, a.src1, a.src2)?;
+ }
+ // TODO: implement named barriers
+ ast::Instruction::Bar(d, _) => {
+ let workgroup_scope = map.get_or_add_constant(
+ builder,
+ &ast::Type::Scalar(ast::ScalarType::U32),
+ &vec_repr(spirv::Scope::Workgroup as u32),
+ )?;
+ let barrier_semantics = match d {
+ ast::BarDetails::SyncAligned => map.get_or_add_constant(
+ builder,
+ &ast::Type::Scalar(ast::ScalarType::U32),
+ &vec_repr(
+ spirv::MemorySemantics::CROSS_WORKGROUP_MEMORY
+ | spirv::MemorySemantics::WORKGROUP_MEMORY
+ | spirv::MemorySemantics::SEQUENTIALLY_CONSISTENT,
+ ),
+ )?,
+ };
+ builder.control_barrier(workgroup_scope, workgroup_scope, barrier_semantics)?;
+ }
+ ast::Instruction::Atom(details, arg) => {
+ emit_atom(builder, map, details, arg)?;
+ }
+ ast::Instruction::AtomCas(details, arg) => {
+ let result_type = map.get_or_add_scalar(builder, details.typ.into());
+ let memory_const = map.get_or_add_constant(
+ builder,
+ &ast::Type::Scalar(ast::ScalarType::U32),
+ &vec_repr(details.scope.to_spirv() as u32),
+ )?;
+ let semantics_const = map.get_or_add_constant(
+ builder,
+ &ast::Type::Scalar(ast::ScalarType::U32),
+ &vec_repr(details.semantics.to_spirv().bits()),
+ )?;
+ builder.atomic_compare_exchange(
+ result_type,
+ Some(arg.dst),
+ arg.src1,
+ memory_const,
+ semantics_const,
+ semantics_const,
+ arg.src3,
+ arg.src2,
+ )?;
+ }
+ ast::Instruction::Div(details, arg) => match details {
+ ast::DivDetails::Unsigned(t) => {
+ let result_type = map.get_or_add_scalar(builder, (*t).into());
+ builder.u_div(result_type, Some(arg.dst), arg.src1, arg.src2)?;
+ }
+ ast::DivDetails::Signed(t) => {
+ let result_type = map.get_or_add_scalar(builder, (*t).into());
+ builder.s_div(result_type, Some(arg.dst), arg.src1, arg.src2)?;
+ }
+ ast::DivDetails::Float(t) => {
+ let result_type = map.get_or_add_scalar(builder, t.typ.into());
+ builder.f_div(result_type, Some(arg.dst), arg.src1, arg.src2)?;
+ emit_float_div_decoration(builder, arg.dst, t.kind);
+ }
+ },
+ ast::Instruction::Sqrt(details, a) => {
+ emit_sqrt(builder, map, opencl, details, a)?;
+ }
+ ast::Instruction::Rsqrt(details, a) => {
+ let result_type = map.get_or_add_scalar(builder, details.typ.into());
+ builder.ext_inst(
+ result_type,
+ Some(a.dst),
+ opencl,
+ spirv::CLOp::native_rsqrt as spirv::Word,
+ &[a.src],
+ )?;
+ }
+ ast::Instruction::Neg(details, arg) => {
+ let result_type = map.get_or_add_scalar(builder, details.typ);
+ let negate_func = if details.typ.kind() == ScalarKind::Float {
+ dr::Builder::f_negate
+ } else {
+ dr::Builder::s_negate
+ };
+ negate_func(builder, result_type, Some(arg.dst), arg.src)?;
+ }
+ ast::Instruction::Sin { arg, .. } => {
+ let result_type = map.get_or_add_scalar(builder, ast::ScalarType::F32);
+ builder.ext_inst(
+ result_type,
+ Some(arg.dst),
+ opencl,
+ spirv::CLOp::sin as u32,
+ [arg.src],
+ )?;
+ }
+ ast::Instruction::Cos { arg, .. } => {
+ let result_type = map.get_or_add_scalar(builder, ast::ScalarType::F32);
+ builder.ext_inst(
+ result_type,
+ Some(arg.dst),
+ opencl,
+ spirv::CLOp::cos as u32,
+ [arg.src],
+ )?;
+ }
+ ast::Instruction::Lg2 { arg, .. } => {
+ let result_type = map.get_or_add_scalar(builder, ast::ScalarType::F32);
+ builder.ext_inst(
+ result_type,
+ Some(arg.dst),
+ opencl,
+ spirv::CLOp::log2 as u32,
+ [arg.src],
+ )?;
+ }
+ ast::Instruction::Ex2 { arg, .. } => {
+ let result_type = map.get_or_add_scalar(builder, ast::ScalarType::F32);
+ builder.ext_inst(
+ result_type,
+ Some(arg.dst),
+ opencl,
+ spirv::CLOp::exp2 as u32,
+ [arg.src],
+ )?;
+ }
+ ast::Instruction::Clz { typ, arg } => {
+ let result_type = map.get_or_add_scalar(builder, (*typ).into());
+ builder.ext_inst(
+ result_type,
+ Some(arg.dst),
+ opencl,
+ spirv::CLOp::clz as u32,
+ [arg.src],
+ )?;
+ }
+ ast::Instruction::Brev { typ, arg } => {
+ let result_type = map.get_or_add_scalar(builder, (*typ).into());
+ builder.bit_reverse(result_type, Some(arg.dst), arg.src)?;
+ }
+ ast::Instruction::Popc { typ, arg } => {
+ let result_type = map.get_or_add_scalar(builder, (*typ).into());
+ builder.bit_count(result_type, Some(arg.dst), arg.src)?;
+ }
+ ast::Instruction::Xor { typ, arg } => {
+ let builder_fn = match typ {
+ ast::BooleanType::Pred => emit_logical_xor_spirv,
+ _ => dr::Builder::bitwise_xor,
+ };
+ let result_type = map.get_or_add_scalar(builder, (*typ).into());
+ builder_fn(builder, result_type, Some(arg.dst), arg.src1, arg.src2)?;
+ }
+ ast::Instruction::Bfe { typ, arg } => {
+ let builder_fn = if typ.is_signed() {
+ dr::Builder::bit_field_s_extract
+ } else {
+ dr::Builder::bit_field_u_extract
+ };
+ let result_type = map.get_or_add_scalar(builder, (*typ).into());
+ builder_fn(
+ builder,
+ result_type,
+ Some(arg.dst),
+ arg.src1,
+ arg.src2,
+ arg.src3,
+ )?;
+ }
+ ast::Instruction::Rem { typ, arg } => {
+ let builder_fn = if typ.is_signed() {
+ dr::Builder::s_mod
+ } else {
+ dr::Builder::u_mod
+ };
+ let result_type = map.get_or_add_scalar(builder, (*typ).into());
+ builder_fn(builder, result_type, Some(arg.dst), arg.src1, arg.src2)?;
+ }
+ },
+ Statement::LoadVar(details) => {
+ emit_load_var(builder, map, details)?;
+ }
+ Statement::StoreVar(details) => {
+ let dst_ptr = match details.member_index {
+ Some(index) => {
+ let result_ptr_type = map.get_or_add(
+ builder,
+ SpirvType::new_pointer(
+ details.typ.clone(),
+ spirv::StorageClass::Function,
+ ),
+ );
+ let index_spirv = map.get_or_add_constant(
+ builder,
+ &ast::Type::Scalar(ast::ScalarType::U32),
+ &vec_repr(index as u32),
+ )?;
+ builder.in_bounds_access_chain(
+ result_ptr_type,
+ None,
+ details.arg.src1,
+ &[index_spirv],
+ )?
+ }
+ None => details.arg.src1,
+ };
+ builder.store(dst_ptr, details.arg.src2, None, [])?;
+ }
+ Statement::RetValue(_, id) => {
+ builder.ret_value(*id)?;
+ }
+ Statement::PtrAccess(PtrAccess {
+ underlying_type,
+ state_space,
+ dst,
+ ptr_src,
+ offset_src,
+ }) => {
+ let u8_pointer = map.get_or_add(
+ builder,
+ SpirvType::from(ast::Type::Pointer(
+ ast::PointerType::Scalar(ast::ScalarType::U8),
+ *state_space,
+ )),
+ );
+ let result_type = map.get_or_add(
+ builder,
+ SpirvType::from(ast::Type::Pointer(underlying_type.clone(), *state_space)),
+ );
+ let ptr_src_u8 = builder.bitcast(u8_pointer, None, *ptr_src)?;
+ let temp = builder.in_bounds_ptr_access_chain(
+ u8_pointer,
+ None,
+ ptr_src_u8,
+ *offset_src,
+ &[],
+ )?;
+ builder.bitcast(result_type, Some(*dst), temp)?;
+ }
+ Statement::RepackVector(repack) => {
+ if repack.is_extract {
+ let scalar_type = map.get_or_add_scalar(builder, repack.typ);
+ for (index, dst_id) in repack.unpacked.iter().enumerate() {
+ builder.composite_extract(
+ scalar_type,
+ Some(*dst_id),
+ repack.packed,
+ &[index as u32],
+ )?;
+ }
+ } else {
+ let vector_type = map.get_or_add(
+ builder,
+ SpirvType::Vector(
+ SpirvScalarKey::from(repack.typ),
+ repack.unpacked.len() as u8,
+ ),
+ );
+ let mut temp_vec = builder.undef(vector_type, None);
+ for (index, src_id) in repack.unpacked.iter().enumerate() {
+ temp_vec = builder.composite_insert(
+ vector_type,
+ None,
+ *src_id,
+ temp_vec,
+ &[index as u32],
+ )?;
+ }
+ builder.copy_object(vector_type, Some(repack.packed), temp_vec)?;
+ }
+ }
+ }
+ }
+ Ok(())
+}
+
+// HACK ALERT
+// For some reason IGC fails linking if the value and shift size are of different type
+fn insert_shift_hack(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ offset_var: spirv::Word,
+ size_of: usize,
+) -> Result<spirv::Word, TranslateError> {
+ let result_type = match size_of {
+ 2 => map.get_or_add_scalar(builder, ast::ScalarType::B16),
+ 8 => map.get_or_add_scalar(builder, ast::ScalarType::B64),
+ 4 => return Ok(offset_var),
+ _ => return Err(error_unreachable()),
+ };
+ Ok(builder.u_convert(result_type, None, offset_var)?)
+}
+
+// TODO: check what kind of assembly do we emit
+fn emit_logical_xor_spirv(
+ builder: &mut dr::Builder,
+ result_type: spirv::Word,
+ result_id: Option<spirv::Word>,
+ op1: spirv::Word,
+ op2: spirv::Word,
+) -> Result<spirv::Word, dr::Error> {
+ let temp_or = builder.logical_or(result_type, None, op1, op2)?;
+ let temp_and = builder.logical_and(result_type, None, op1, op2)?;
+ let temp_neg = builder.logical_not(result_type, None, temp_and)?;
+ builder.logical_and(result_type, result_id, temp_or, temp_neg)
+}
+
+fn emit_sqrt(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ opencl: spirv::Word,
+ details: &ast::SqrtDetails,
+ a: &ast::Arg2<ExpandedArgParams>,
+) -> Result<(), TranslateError> {
+ let result_type = map.get_or_add_scalar(builder, details.typ.into());
+ let (ocl_op, rounding) = match details.kind {
+ ast::SqrtKind::Approx => (spirv::CLOp::native_sqrt, None),
+ ast::SqrtKind::Rounding(rnd) => (spirv::CLOp::sqrt, Some(rnd)),
+ };
+ builder.ext_inst(
+ result_type,
+ Some(a.dst),
+ opencl,
+ ocl_op as spirv::Word,
+ &[a.src],
+ )?;
+ emit_rounding_decoration(builder, a.dst, rounding);
+ Ok(())
+}
+
+fn emit_float_div_decoration(builder: &mut dr::Builder, dst: spirv::Word, kind: ast::DivFloatKind) {
+ match kind {
+ ast::DivFloatKind::Approx => {
+ builder.decorate(
+ dst,
+ spirv::Decoration::FPFastMathMode,
+ &[dr::Operand::FPFastMathMode(
+ spirv::FPFastMathMode::ALLOW_RECIP,
+ )],
+ );
+ }
+ ast::DivFloatKind::Rounding(rnd) => {
+ emit_rounding_decoration(builder, dst, Some(rnd));
+ }
+ ast::DivFloatKind::Full => {}
+ }
+}
+
+fn emit_atom(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ details: &ast::AtomDetails,
+ arg: &ast::Arg3<ExpandedArgParams>,
+) -> Result<(), TranslateError> {
+ let (spirv_op, typ) = match details.inner {
+ ast::AtomInnerDetails::Bit { op, typ } => {
+ let spirv_op = match op {
+ ast::AtomBitOp::And => dr::Builder::atomic_and,
+ ast::AtomBitOp::Or => dr::Builder::atomic_or,
+ ast::AtomBitOp::Xor => dr::Builder::atomic_xor,
+ ast::AtomBitOp::Exchange => dr::Builder::atomic_exchange,
+ };
+ (spirv_op, ast::ScalarType::from(typ))
+ }
+ ast::AtomInnerDetails::Unsigned { op, typ } => {
+ let spirv_op = match op {
+ ast::AtomUIntOp::Add => dr::Builder::atomic_i_add,
+ ast::AtomUIntOp::Inc | ast::AtomUIntOp::Dec => {
+ return Err(error_unreachable());
+ }
+ ast::AtomUIntOp::Min => dr::Builder::atomic_u_min,
+ ast::AtomUIntOp::Max => dr::Builder::atomic_u_max,
+ };
+ (spirv_op, typ.into())
+ }
+ ast::AtomInnerDetails::Signed { op, typ } => {
+ let spirv_op = match op {
+ ast::AtomSIntOp::Add => dr::Builder::atomic_i_add,
+ ast::AtomSIntOp::Min => dr::Builder::atomic_s_min,
+ ast::AtomSIntOp::Max => dr::Builder::atomic_s_max,
+ };
+ (spirv_op, typ.into())
+ }
+ // TODO: Hardware is capable of this, implement it through builtin
+ ast::AtomInnerDetails::Float { .. } => todo!(),
+ };
+ let result_type = map.get_or_add_scalar(builder, typ);
+ let memory_const = map.get_or_add_constant(
+ builder,
+ &ast::Type::Scalar(ast::ScalarType::U32),
+ &vec_repr(details.scope.to_spirv() as u32),
+ )?;
+ let semantics_const = map.get_or_add_constant(
+ builder,
+ &ast::Type::Scalar(ast::ScalarType::U32),
+ &vec_repr(details.semantics.to_spirv().bits()),
+ )?;
+ spirv_op(
+ builder,
+ result_type,
+ Some(arg.dst),
+ arg.src1,
+ memory_const,
+ semantics_const,
+ arg.src2,
+ )?;
+ Ok(())
+}
+
+#[derive(Clone)]
+struct PtxImplImport {
+ out_arg: ast::Type,
+ fn_id: u32,
+ in_args: Vec<ast::Type>,
+}
+
+fn ptx_semantics_name(sema: ast::AtomSemantics) -> &'static str {
+ match sema {
+ ast::AtomSemantics::Relaxed => "relaxed",
+ ast::AtomSemantics::Acquire => "acquire",
+ ast::AtomSemantics::Release => "release",
+ ast::AtomSemantics::AcquireRelease => "acq_rel",
+ }
+}
+
+fn ptx_scope_name(scope: ast::MemScope) -> &'static str {
+ match scope {
+ ast::MemScope::Cta => "cta",
+ ast::MemScope::Gpu => "gpu",
+ ast::MemScope::Sys => "sys",
+ }
+}
+
+fn ptx_space_name(space: ast::AtomSpace) -> &'static str {
+ match space {
+ ast::AtomSpace::Generic => "generic",
+ ast::AtomSpace::Global => "global",
+ ast::AtomSpace::Shared => "shared",
+ }
+}
+
+fn emit_mul_float(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ ctr: &ast::ArithFloat,
+ arg: &ast::Arg3<ExpandedArgParams>,
+) -> Result<(), dr::Error> {
+ if ctr.saturate {
+ todo!()
+ }
+ let result_type = map.get_or_add_scalar(builder, ctr.typ.into());
+ builder.f_mul(result_type, Some(arg.dst), arg.src1, arg.src2)?;
+ emit_rounding_decoration(builder, arg.dst, ctr.rounding);
+ Ok(())
+}
+
+fn emit_rcp(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ desc: &ast::RcpDetails,
+ a: &ast::Arg2<ExpandedArgParams>,
+) -> Result<(), TranslateError> {
+ let (instr_type, constant) = if desc.is_f64 {
+ (ast::ScalarType::F64, vec_repr(1.0f64))
+ } else {
+ (ast::ScalarType::F32, vec_repr(1.0f32))
+ };
+ let one = map.get_or_add_constant(builder, &ast::Type::Scalar(instr_type), &constant)?;
+ let result_type = map.get_or_add_scalar(builder, instr_type);
+ builder.f_div(result_type, Some(a.dst), one, a.src)?;
+ emit_rounding_decoration(builder, a.dst, desc.rounding);
+ builder.decorate(
+ a.dst,
+ spirv::Decoration::FPFastMathMode,
+ &[dr::Operand::FPFastMathMode(
+ spirv::FPFastMathMode::ALLOW_RECIP,
+ )],
+ );
+ Ok(())
+}
+
+fn vec_repr<T: Copy>(t: T) -> Vec<u8> {
+ let mut result = vec![0; mem::size_of::<T>()];
+ unsafe { std::ptr::copy_nonoverlapping(&t, result.as_mut_ptr() as *mut _, 1) };
+ result
+}
+
+fn emit_variable(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ var: &ast::Variable<ast::VariableType, spirv::Word>,
+) -> Result<(), TranslateError> {
+ let (must_init, st_class) = match var.v_type {
+ ast::VariableType::Reg(_) | ast::VariableType::Param(_) | ast::VariableType::Local(_) => {
+ (false, spirv::StorageClass::Function)
+ }
+ ast::VariableType::Global(_) => (true, spirv::StorageClass::CrossWorkgroup),
+ ast::VariableType::Shared(_) => (false, spirv::StorageClass::Workgroup),
+ };
+ let initalizer = if var.array_init.len() > 0 {
+ Some(map.get_or_add_constant(
+ builder,
+ &ast::Type::from(var.v_type.clone()),
+ &*var.array_init,
+ )?)
+ } else if must_init {
+ let type_id = map.get_or_add(
+ builder,
+ SpirvType::from(ast::Type::from(var.v_type.clone())),
+ );
+ Some(builder.constant_null(type_id, None))
+ } else {
+ None
+ };
+ let ptr_type_id = map.get_or_add(
+ builder,
+ SpirvType::new_pointer(ast::Type::from(var.v_type.clone()), st_class),
+ );
+ builder.variable(ptr_type_id, Some(var.name), st_class, initalizer);
+ if let Some(align) = var.align {
+ builder.decorate(
+ var.name,
+ spirv::Decoration::Alignment,
+ &[dr::Operand::LiteralInt32(align)],
+ );
+ }
+ Ok(())
+}
+
+fn emit_mad_uint(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ opencl: spirv::Word,
+ desc: &ast::MulUInt,
+ arg: &ast::Arg4<ExpandedArgParams>,
+) -> Result<(), dr::Error> {
+ let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(desc.typ)));
+ match desc.control {
+ ast::MulIntControl::Low => {
+ let mul_result = builder.i_mul(inst_type, None, arg.src1, arg.src2)?;
+ builder.i_add(inst_type, Some(arg.dst), arg.src3, mul_result)?;
+ }
+ ast::MulIntControl::High => {
+ builder.ext_inst(
+ inst_type,
+ Some(arg.dst),
+ opencl,
+ spirv::CLOp::u_mad_hi as spirv::Word,
+ [arg.src1, arg.src2, arg.src3],
+ )?;
+ }
+ ast::MulIntControl::Wide => todo!(),
+ };
+ Ok(())
+}
+
+fn emit_mad_sint(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ opencl: spirv::Word,
+ desc: &ast::MulSInt,
+ arg: &ast::Arg4<ExpandedArgParams>,
+) -> Result<(), dr::Error> {
+ let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(desc.typ)));
+ match desc.control {
+ ast::MulIntControl::Low => {
+ let mul_result = builder.i_mul(inst_type, None, arg.src1, arg.src2)?;
+ builder.i_add(inst_type, Some(arg.dst), arg.src3, mul_result)?;
+ }
+ ast::MulIntControl::High => {
+ builder.ext_inst(
+ inst_type,
+ Some(arg.dst),
+ opencl,
+ spirv::CLOp::s_mad_hi as spirv::Word,
+ [arg.src1, arg.src2, arg.src3],
+ )?;
+ }
+ ast::MulIntControl::Wide => todo!(),
+ };
+ Ok(())
+}
+
+fn emit_mad_float(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ opencl: spirv::Word,
+ desc: &ast::ArithFloat,
+ arg: &ast::Arg4<ExpandedArgParams>,
+) -> Result<(), dr::Error> {
+ let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(desc.typ)));
+ builder.ext_inst(
+ inst_type,
+ Some(arg.dst),
+ opencl,
+ spirv::CLOp::mad as spirv::Word,
+ [arg.src1, arg.src2, arg.src3],
+ )?;
+ Ok(())
+}
+
+fn emit_add_float(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ desc: &ast::ArithFloat,
+ arg: &ast::Arg3<ExpandedArgParams>,
+) -> Result<(), dr::Error> {
+ let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(desc.typ)));
+ builder.f_add(inst_type, Some(arg.dst), arg.src1, arg.src2)?;
+ emit_rounding_decoration(builder, arg.dst, desc.rounding);
+ Ok(())
+}
+
+fn emit_sub_float(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ desc: &ast::ArithFloat,
+ arg: &ast::Arg3<ExpandedArgParams>,
+) -> Result<(), dr::Error> {
+ let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(desc.typ)));
+ builder.f_sub(inst_type, Some(arg.dst), arg.src1, arg.src2)?;
+ emit_rounding_decoration(builder, arg.dst, desc.rounding);
+ Ok(())
+}
+
+fn emit_min(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ opencl: spirv::Word,
+ desc: &ast::MinMaxDetails,
+ arg: &ast::Arg3<ExpandedArgParams>,
+) -> Result<(), dr::Error> {
+ let cl_op = match desc {
+ ast::MinMaxDetails::Signed(_) => spirv::CLOp::s_min,
+ ast::MinMaxDetails::Unsigned(_) => spirv::CLOp::u_min,
+ ast::MinMaxDetails::Float(_) => spirv::CLOp::fmin,
+ };
+ let inst_type = map.get_or_add(builder, SpirvType::from(desc.get_type()));
+ builder.ext_inst(
+ inst_type,
+ Some(arg.dst),
+ opencl,
+ cl_op as spirv::Word,
+ [arg.src1, arg.src2],
+ )?;
+ Ok(())
+}
+
+fn emit_max(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ opencl: spirv::Word,
+ desc: &ast::MinMaxDetails,
+ arg: &ast::Arg3<ExpandedArgParams>,
+) -> Result<(), dr::Error> {
+ let cl_op = match desc {
+ ast::MinMaxDetails::Signed(_) => spirv::CLOp::s_max,
+ ast::MinMaxDetails::Unsigned(_) => spirv::CLOp::u_max,
+ ast::MinMaxDetails::Float(_) => spirv::CLOp::fmax,
+ };
+ let inst_type = map.get_or_add(builder, SpirvType::from(desc.get_type()));
+ builder.ext_inst(
+ inst_type,
+ Some(arg.dst),
+ opencl,
+ cl_op as spirv::Word,
+ [arg.src1, arg.src2],
+ )?;
+ Ok(())
+}
+
+fn emit_cvt(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ opencl: spirv::Word,
+ dets: &ast::CvtDetails,
+ arg: &ast::Arg2<ExpandedArgParams>,
+) -> Result<(), TranslateError> {
+ match dets {
+ ast::CvtDetails::FloatFromFloat(desc) => {
+ if desc.saturate {
+ todo!()
+ }
+ let dest_t: ast::ScalarType = desc.dst.into();
+ let result_type = map.get_or_add(builder, SpirvType::from(dest_t));
+ if desc.dst == desc.src {
+ match desc.rounding {
+ Some(ast::RoundingMode::NearestEven) => {
+ builder.ext_inst(
+ result_type,
+ Some(arg.dst),
+ opencl,
+ spirv::CLOp::rint as u32,
+ [arg.src],
+ )?;
+ }
+ Some(ast::RoundingMode::Zero) => {
+ builder.ext_inst(
+ result_type,
+ Some(arg.dst),
+ opencl,
+ spirv::CLOp::trunc as u32,
+ [arg.src],
+ )?;
+ }
+ Some(ast::RoundingMode::NegativeInf) => {
+ builder.ext_inst(
+ result_type,
+ Some(arg.dst),
+ opencl,
+ spirv::CLOp::floor as u32,
+ [arg.src],
+ )?;
+ }
+ Some(ast::RoundingMode::PositiveInf) => {
+ builder.ext_inst(
+ result_type,
+ Some(arg.dst),
+ opencl,
+ spirv::CLOp::ceil as u32,
+ [arg.src],
+ )?;
+ }
+ None => {
+ builder.copy_object(result_type, Some(arg.dst), arg.src)?;
+ }
+ }
+ } else {
+ builder.f_convert(result_type, Some(arg.dst), arg.src)?;
+ emit_rounding_decoration(builder, arg.dst, desc.rounding);
+ }
+ }
+ ast::CvtDetails::FloatFromInt(desc) => {
+ if desc.saturate {
+ todo!()
+ }
+ let dest_t: ast::ScalarType = desc.dst.into();
+ let result_type = map.get_or_add(builder, SpirvType::from(dest_t));
+ if desc.src.is_signed() {
+ builder.convert_s_to_f(result_type, Some(arg.dst), arg.src)?;
+ } else {
+ builder.convert_u_to_f(result_type, Some(arg.dst), arg.src)?;
+ }
+ emit_rounding_decoration(builder, arg.dst, desc.rounding);
+ }
+ ast::CvtDetails::IntFromFloat(desc) => {
+ let dest_t: ast::ScalarType = desc.dst.into();
+ let result_type = map.get_or_add(builder, SpirvType::from(dest_t));
+ if desc.dst.is_signed() {
+ builder.convert_f_to_s(result_type, Some(arg.dst), arg.src)?;
+ } else {
+ builder.convert_f_to_u(result_type, Some(arg.dst), arg.src)?;
+ }
+ emit_rounding_decoration(builder, arg.dst, desc.rounding);
+ emit_saturating_decoration(builder, arg.dst, desc.saturate);
+ }
+ ast::CvtDetails::IntFromInt(desc) => {
+ let dest_t: ast::ScalarType = desc.dst.into();
+ let src_t: ast::ScalarType = desc.src.into();
+ // first do shortening/widening
+ let src = if desc.dst.width() != desc.src.width() {
+ let new_dst = if dest_t.kind() == src_t.kind() {
+ arg.dst
+ } else {
+ builder.id()
+ };
+ let cv = ImplicitConversion {
+ src: arg.src,
+ dst: new_dst,
+ from: ast::Type::Scalar(src_t),
+ to: ast::Type::Scalar(ast::ScalarType::from_parts(
+ dest_t.size_of(),
+ src_t.kind(),
+ )),
+ kind: ConversionKind::Default,
+ src_sema: ArgumentSemantics::Default,
+ dst_sema: ArgumentSemantics::Default,
+ };
+ emit_implicit_conversion(builder, map, &cv)?;
+ new_dst
+ } else {
+ arg.src
+ };
+ if dest_t.kind() == src_t.kind() {
+ return Ok(());
+ }
+ // now do actual conversion
+ let result_type = map.get_or_add(builder, SpirvType::from(dest_t));
+ if desc.saturate {
+ if desc.dst.is_signed() {
+ builder.sat_convert_u_to_s(result_type, Some(arg.dst), src)?;
+ } else {
+ builder.sat_convert_s_to_u(result_type, Some(arg.dst), src)?;
+ }
+ } else {
+ builder.bitcast(result_type, Some(arg.dst), src)?;
+ }
+ }
+ }
+ Ok(())
+}
+
+fn emit_saturating_decoration(builder: &mut dr::Builder, dst: u32, saturate: bool) {
+ if saturate {
+ builder.decorate(dst, spirv::Decoration::SaturatedConversion, []);
+ }
+}
+
+fn emit_rounding_decoration(
+ builder: &mut dr::Builder,
+ dst: spirv::Word,
+ rounding: Option<ast::RoundingMode>,
+) {
+ if let Some(rounding) = rounding {
+ builder.decorate(
+ dst,
+ spirv::Decoration::FPRoundingMode,
+ [rounding.to_spirv()],
+ );
+ }
+}
+
+impl ast::RoundingMode {
+ fn to_spirv(self) -> rspirv::dr::Operand {
+ let mode = match self {
+ ast::RoundingMode::NearestEven => spirv::FPRoundingMode::RTE,
+ ast::RoundingMode::Zero => spirv::FPRoundingMode::RTZ,
+ ast::RoundingMode::PositiveInf => spirv::FPRoundingMode::RTP,
+ ast::RoundingMode::NegativeInf => spirv::FPRoundingMode::RTN,
+ };
+ rspirv::dr::Operand::FPRoundingMode(mode)
+ }
+}
+
+fn emit_setp(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ setp: &ast::SetpData,
+ arg: &ast::Arg4Setp<ExpandedArgParams>,
+) -> Result<(), dr::Error> {
+ let result_type = map.get_or_add(builder, SpirvType::Base(SpirvScalarKey::Pred));
+ let result_id = Some(arg.dst1);
+ let operand_1 = arg.src1;
+ let operand_2 = arg.src2;
+ match (setp.cmp_op, setp.typ.kind()) {
+ (ast::SetpCompareOp::Eq, ScalarKind::Signed)
+ | (ast::SetpCompareOp::Eq, ScalarKind::Unsigned)
+ | (ast::SetpCompareOp::Eq, ScalarKind::Bit) => {
+ builder.i_equal(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::Eq, ScalarKind::Float) => {
+ builder.f_ord_equal(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::NotEq, ScalarKind::Signed)
+ | (ast::SetpCompareOp::NotEq, ScalarKind::Unsigned)
+ | (ast::SetpCompareOp::NotEq, ScalarKind::Bit) => {
+ builder.i_not_equal(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::NotEq, ScalarKind::Float) => {
+ builder.f_ord_not_equal(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::Less, ScalarKind::Unsigned)
+ | (ast::SetpCompareOp::Less, ScalarKind::Bit) => {
+ builder.u_less_than(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::Less, ScalarKind::Signed) => {
+ builder.s_less_than(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::Less, ScalarKind::Float) => {
+ builder.f_ord_less_than(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::LessOrEq, ScalarKind::Unsigned)
+ | (ast::SetpCompareOp::LessOrEq, ScalarKind::Bit) => {
+ builder.u_less_than_equal(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::LessOrEq, ScalarKind::Signed) => {
+ builder.s_less_than_equal(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::LessOrEq, ScalarKind::Float) => {
+ builder.f_ord_less_than_equal(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::Greater, ScalarKind::Unsigned)
+ | (ast::SetpCompareOp::Greater, ScalarKind::Bit) => {
+ builder.u_greater_than(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::Greater, ScalarKind::Signed) => {
+ builder.s_greater_than(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::Greater, ScalarKind::Float) => {
+ builder.f_ord_greater_than(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::GreaterOrEq, ScalarKind::Unsigned)
+ | (ast::SetpCompareOp::GreaterOrEq, ScalarKind::Bit) => {
+ builder.u_greater_than_equal(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::GreaterOrEq, ScalarKind::Signed) => {
+ builder.s_greater_than_equal(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::GreaterOrEq, ScalarKind::Float) => {
+ builder.f_ord_greater_than_equal(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::NanEq, _) => {
+ builder.f_unord_equal(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::NanNotEq, _) => {
+ builder.f_unord_not_equal(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::NanLess, _) => {
+ builder.f_unord_less_than(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::NanLessOrEq, _) => {
+ builder.f_unord_less_than_equal(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::NanGreater, _) => {
+ builder.f_unord_greater_than(result_type, result_id, operand_1, operand_2)
+ }
+ (ast::SetpCompareOp::NanGreaterOrEq, _) => {
+ builder.f_unord_greater_than_equal(result_type, result_id, operand_1, operand_2)
+ }
+ _ => todo!(),
+ }?;
+ Ok(())
+}
+
+fn emit_mul_sint(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ opencl: spirv::Word,
+ desc: &ast::MulSInt,
+ arg: &ast::Arg3<ExpandedArgParams>,
+) -> Result<(), dr::Error> {
+ let instruction_type = ast::ScalarType::from(desc.typ);
+ let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(desc.typ)));
+ match desc.control {
+ ast::MulIntControl::Low => {
+ builder.i_mul(inst_type, Some(arg.dst), arg.src1, arg.src2)?;
+ }
+ ast::MulIntControl::High => {
+ builder.ext_inst(
+ inst_type,
+ Some(arg.dst),
+ opencl,
+ spirv::CLOp::s_mul_hi as spirv::Word,
+ [arg.src1, arg.src2],
+ )?;
+ }
+ ast::MulIntControl::Wide => {
+ let mul_ext_type = SpirvType::Struct(vec![
+ SpirvScalarKey::from(instruction_type),
+ SpirvScalarKey::from(instruction_type),
+ ]);
+ let mul_ext_type_id = map.get_or_add(builder, mul_ext_type);
+ let mul = builder.s_mul_extended(mul_ext_type_id, None, arg.src1, arg.src2)?;
+ let instr_width = instruction_type.size_of();
+ let instr_kind = instruction_type.kind();
+ let dst_type = ast::ScalarType::from_parts(instr_width * 2, instr_kind);
+ let dst_type_id = map.get_or_add_scalar(builder, dst_type);
+ struct2_bitcast_to_wide(
+ builder,
+ map,
+ SpirvScalarKey::from(instruction_type),
+ inst_type,
+ arg.dst,
+ dst_type_id,
+ mul,
+ )?;
+ }
+ }
+ Ok(())
+}
+
+fn emit_mul_uint(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ opencl: spirv::Word,
+ desc: &ast::MulUInt,
+ arg: &ast::Arg3<ExpandedArgParams>,
+) -> Result<(), dr::Error> {
+ let instruction_type = ast::ScalarType::from(desc.typ);
+ let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(desc.typ)));
+ match desc.control {
+ ast::MulIntControl::Low => {
+ builder.i_mul(inst_type, Some(arg.dst), arg.src1, arg.src2)?;
+ }
+ ast::MulIntControl::High => {
+ builder.ext_inst(
+ inst_type,
+ Some(arg.dst),
+ opencl,
+ spirv::CLOp::u_mul_hi as spirv::Word,
+ [arg.src1, arg.src2],
+ )?;
+ }
+ ast::MulIntControl::Wide => {
+ let mul_ext_type = SpirvType::Struct(vec![
+ SpirvScalarKey::from(instruction_type),
+ SpirvScalarKey::from(instruction_type),
+ ]);
+ let mul_ext_type_id = map.get_or_add(builder, mul_ext_type);
+ let mul = builder.u_mul_extended(mul_ext_type_id, None, arg.src1, arg.src2)?;
+ let instr_width = instruction_type.size_of();
+ let instr_kind = instruction_type.kind();
+ let dst_type = ast::ScalarType::from_parts(instr_width * 2, instr_kind);
+ let dst_type_id = map.get_or_add_scalar(builder, dst_type);
+ struct2_bitcast_to_wide(
+ builder,
+ map,
+ SpirvScalarKey::from(instruction_type),
+ inst_type,
+ arg.dst,
+ dst_type_id,
+ mul,
+ )?;
+ }
+ }
+ Ok(())
+}
+
+// Surprisingly, structs can't be bitcast, so we route everything through a vector
+fn struct2_bitcast_to_wide(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ base_type_key: SpirvScalarKey,
+ instruction_type: spirv::Word,
+ dst: spirv::Word,
+ dst_type_id: spirv::Word,
+ src: spirv::Word,
+) -> Result<(), dr::Error> {
+ let low_bits = builder.composite_extract(instruction_type, None, src, [0])?;
+ let high_bits = builder.composite_extract(instruction_type, None, src, [1])?;
+ let vector_type = map.get_or_add(builder, SpirvType::Vector(base_type_key, 2));
+ let vector = builder.composite_construct(vector_type, None, [low_bits, high_bits])?;
+ builder.bitcast(dst_type_id, Some(dst), vector)?;
+ Ok(())
+}
+
+fn emit_abs(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ opencl: spirv::Word,
+ d: &ast::AbsDetails,
+ arg: &ast::Arg2<ExpandedArgParams>,
+) -> Result<(), dr::Error> {
+ let scalar_t = ast::ScalarType::from(d.typ);
+ let result_type = map.get_or_add(builder, SpirvType::from(scalar_t));
+ let cl_abs = if scalar_t.kind() == ScalarKind::Signed {
+ spirv::CLOp::s_abs
+ } else {
+ spirv::CLOp::fabs
+ };
+ builder.ext_inst(
+ result_type,
+ Some(arg.dst),
+ opencl,
+ cl_abs as spirv::Word,
+ [arg.src],
+ )?;
+ Ok(())
+}
+
+fn emit_add_int(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ typ: ast::ScalarType,
+ saturate: bool,
+ arg: &ast::Arg3<ExpandedArgParams>,
+) -> Result<(), dr::Error> {
+ if saturate {
+ todo!()
+ }
+ let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(typ)));
+ builder.i_add(inst_type, Some(arg.dst), arg.src1, arg.src2)?;
+ Ok(())
+}
+
+fn emit_sub_int(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ typ: ast::ScalarType,
+ saturate: bool,
+ arg: &ast::Arg3<ExpandedArgParams>,
+) -> Result<(), dr::Error> {
+ if saturate {
+ todo!()
+ }
+ let inst_type = map.get_or_add(builder, SpirvType::from(ast::ScalarType::from(typ)));
+ builder.i_sub(inst_type, Some(arg.dst), arg.src1, arg.src2)?;
+ Ok(())
+}
+
+fn emit_implicit_conversion(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ cv: &ImplicitConversion,
+) -> Result<(), TranslateError> {
+ let from_parts = cv.from.to_parts();
+ let to_parts = cv.to.to_parts();
+ match (from_parts.kind, to_parts.kind, cv.kind) {
+ (_, _, ConversionKind::PtrToBit(typ)) => {
+ let dst_type = map.get_or_add_scalar(builder, typ.into());
+ builder.convert_ptr_to_u(dst_type, Some(cv.dst), cv.src)?;
+ }
+ (_, _, ConversionKind::BitToPtr(_)) => {
+ let dst_type = map.get_or_add(builder, SpirvType::from(cv.to.clone()));
+ builder.convert_u_to_ptr(dst_type, Some(cv.dst), cv.src)?;
+ }
+ (TypeKind::Scalar, TypeKind::Scalar, ConversionKind::Default) => {
+ if from_parts.width == to_parts.width {
+ let dst_type = map.get_or_add(builder, SpirvType::from(cv.to.clone()));
+ if from_parts.scalar_kind != ScalarKind::Float
+ && to_parts.scalar_kind != ScalarKind::Float
+ {
+ // It is noop, but another instruction expects result of this conversion
+ builder.copy_object(dst_type, Some(cv.dst), cv.src)?;
+ } else {
+ builder.bitcast(dst_type, Some(cv.dst), cv.src)?;
+ }
+ } else {
+ // This block is safe because it's illegal to implictly convert between floating point instructions
+ let same_width_bit_type = map.get_or_add(
+ builder,
+ SpirvType::from(ast::Type::from_parts(TypeParts {
+ scalar_kind: ScalarKind::Bit,
+ ..from_parts
+ })),
+ );
+ let same_width_bit_value = builder.bitcast(same_width_bit_type, None, cv.src)?;
+ let wide_bit_type = ast::Type::from_parts(TypeParts {
+ scalar_kind: ScalarKind::Bit,
+ ..to_parts
+ });
+ let wide_bit_type_spirv =
+ map.get_or_add(builder, SpirvType::from(wide_bit_type.clone()));
+ if to_parts.scalar_kind == ScalarKind::Unsigned
+ || to_parts.scalar_kind == ScalarKind::Bit
+ {
+ builder.u_convert(wide_bit_type_spirv, Some(cv.dst), same_width_bit_value)?;
+ } else {
+ let wide_bit_value =
+ builder.u_convert(wide_bit_type_spirv, None, same_width_bit_value)?;
+ emit_implicit_conversion(
+ builder,
+ map,
+ &ImplicitConversion {
+ src: wide_bit_value,
+ dst: cv.dst,
+ from: wide_bit_type,
+ to: cv.to.clone(),
+ kind: ConversionKind::Default,
+ src_sema: cv.src_sema,
+ dst_sema: cv.dst_sema,
+ },
+ )?;
+ }
+ }
+ }
+ (TypeKind::Scalar, TypeKind::Scalar, ConversionKind::SignExtend) => todo!(),
+ (TypeKind::Vector, TypeKind::Scalar, ConversionKind::Default)
+ | (TypeKind::Scalar, TypeKind::Array, ConversionKind::Default)
+ | (TypeKind::Array, TypeKind::Scalar, ConversionKind::Default) => {
+ let into_type = map.get_or_add(builder, SpirvType::from(cv.to.clone()));
+ builder.bitcast(into_type, Some(cv.dst), cv.src)?;
+ }
+ (_, _, ConversionKind::PtrToPtr { spirv_ptr }) => {
+ let result_type = if spirv_ptr {
+ map.get_or_add(
+ builder,
+ SpirvType::Pointer(
+ Box::new(SpirvType::from(cv.to.clone())),
+ spirv::StorageClass::Function,
+ ),
+ )
+ } else {
+ map.get_or_add(builder, SpirvType::from(cv.to.clone()))
+ };
+ builder.bitcast(result_type, Some(cv.dst), cv.src)?;
+ }
+ _ => unreachable!(),
+ }
+ Ok(())
+}
+
+fn emit_load_var(
+ builder: &mut dr::Builder,
+ map: &mut TypeWordMap,
+ details: &LoadVarDetails,
+) -> Result<(), TranslateError> {
+ let result_type = map.get_or_add(builder, SpirvType::from(details.typ.clone()));
+ match details.member_index {
+ Some((index, Some(width))) => {
+ let vector_type = match details.typ {
+ ast::Type::Scalar(scalar_t) => ast::Type::Vector(scalar_t, width),
+ _ => return Err(TranslateError::MismatchedType),
+ };
+ let vector_type_spirv = map.get_or_add(builder, SpirvType::from(vector_type));
+ let vector_temp = builder.load(vector_type_spirv, None, details.arg.src, None, [])?;
+ builder.composite_extract(
+ result_type,
+ Some(details.arg.dst),
+ vector_temp,
+ &[index as u32],
+ )?;
+ }
+ Some((index, None)) => {
+ let result_ptr_type = map.get_or_add(
+ builder,
+ SpirvType::new_pointer(details.typ.clone(), spirv::StorageClass::Function),
+ );
+ let index_spirv = map.get_or_add_constant(
+ builder,
+ &ast::Type::Scalar(ast::ScalarType::U32),
+ &vec_repr(index as u32),
+ )?;
+ let src = builder.in_bounds_access_chain(
+ result_ptr_type,
+ None,
+ details.arg.src,
+ &[index_spirv],
+ )?;
+ builder.load(result_type, Some(details.arg.dst), src, None, [])?;
+ }
+ None => {
+ builder.load(
+ result_type,
+ Some(details.arg.dst),
+ details.arg.src,
+ None,
+ [],
+ )?;
+ }
+ };
+ Ok(())
+}
+
+fn normalize_identifiers<'a, 'b>(
+ id_defs: &mut FnStringIdResolver<'a, 'b>,
+ fn_defs: &GlobalFnDeclResolver<'a, 'b>,
+ func: Vec<ast::Statement<ast::ParsedArgParams<'a>>>,
+) -> Result<Vec<NormalizedStatement>, TranslateError> {
+ for s in func.iter() {
+ match s {
+ ast::Statement::Label(id) => {
+ id_defs.add_def(*id, None, false);
+ }
+ _ => (),
+ }
+ }
+ let mut result = Vec::new();
+ for s in func {
+ expand_map_variables(id_defs, fn_defs, &mut result, s)?;
+ }
+ Ok(result)
+}
+
+fn expand_map_variables<'a, 'b>(
+ id_defs: &mut FnStringIdResolver<'a, 'b>,
+ fn_defs: &GlobalFnDeclResolver<'a, 'b>,
+ result: &mut Vec<NormalizedStatement>,
+ s: ast::Statement<ast::ParsedArgParams<'a>>,
+) -> Result<(), TranslateError> {
+ match s {
+ ast::Statement::Block(block) => {
+ id_defs.start_block();
+ for s in block {
+ expand_map_variables(id_defs, fn_defs, result, s)?;
+ }
+ id_defs.end_block();
+ }
+ ast::Statement::Label(name) => result.push(Statement::Label(id_defs.get_id(name)?)),
+ ast::Statement::Instruction(p, i) => result.push(Statement::Instruction((
+ p.map(|p| p.map_variable(&mut |id| id_defs.get_id(id)))
+ .transpose()?,
+ i.map_variable(&mut |id| id_defs.get_id(id))?,
+ ))),
+ ast::Statement::Variable(var) => {
+ let mut var_type = ast::Type::from(var.var.v_type.clone());
+ let mut is_variable = false;
+ var_type = match var.var.v_type {
+ ast::VariableType::Reg(_) => {
+ is_variable = true;
+ var_type
+ }
+ ast::VariableType::Shared(_) => {
+ // If it's a pointer it will be translated to a method parameter later
+ if let ast::Type::Pointer(..) = var_type {
+ is_variable = true;
+ var_type
+ } else {
+ var_type.param_pointer_to(ast::LdStateSpace::Shared)?
+ }
+ }
+ ast::VariableType::Global(_) => {
+ var_type.param_pointer_to(ast::LdStateSpace::Global)?
+ }
+ ast::VariableType::Param(_) => {
+ var_type.param_pointer_to(ast::LdStateSpace::Param)?
+ }
+ ast::VariableType::Local(_) => {
+ var_type.param_pointer_to(ast::LdStateSpace::Local)?
+ }
+ };
+ match var.count {
+ Some(count) => {
+ for new_id in id_defs.add_defs(var.var.name, count, var_type, is_variable) {
+ result.push(Statement::Variable(ast::Variable {
+ align: var.var.align,
+ v_type: var.var.v_type.clone(),
+ name: new_id,
+ array_init: var.var.array_init.clone(),
+ }))
+ }
+ }
+ None => {
+ let new_id = id_defs.add_def(var.var.name, Some(var_type), is_variable);
+ result.push(Statement::Variable(ast::Variable {
+ align: var.var.align,
+ v_type: var.var.v_type.clone(),
+ name: new_id,
+ array_init: var.var.array_init,
+ }));
+ }
+ }
+ }
+ };
+ Ok(())
+}
+
+// TODO: detect more patterns (mov, call via reg, call via param)
+// TODO: don't convert to ptr if the register is not ultimately used for ld/st
+// TODO: once insert_mem_ssa_statements is moved to later, move this pass after
+// argument expansion
+// TODO: propagate through calls?
+fn convert_to_stateful_memory_access<'a>(
+ func_args: &mut SpirvMethodDecl,
+ func_body: Vec<TypedStatement>,
+ id_defs: &mut NumericIdResolver<'a>,
+) -> Result<Vec<TypedStatement>, TranslateError> {
+ let func_args_64bit = func_args
+ .input
+ .iter()
+ .filter_map(|arg| match arg.v_type {
+ ast::Type::Scalar(ast::ScalarType::U64)
+ | ast::Type::Scalar(ast::ScalarType::B64)
+ | ast::Type::Scalar(ast::ScalarType::S64) => Some(arg.name),
+ _ => None,
+ })
+ .collect::<HashSet<_>>();
+ let mut stateful_markers = Vec::new();
+ let mut stateful_init_reg = MultiHashMap::new();
+ for statement in func_body.iter() {
+ match statement {
+ Statement::Instruction(ast::Instruction::Cvta(
+ ast::CvtaDetails {
+ to: ast::CvtaStateSpace::Global,
+ size: ast::CvtaSize::U64,
+ from: ast::CvtaStateSpace::Generic,
+ },
+ arg,
+ )) => {
+ if let (TypedOperand::Reg(dst), Some(src)) =
+ (arg.dst, arg.src.upcast().underlying())
+ {
+ if is_64_bit_integer(id_defs, *src) && is_64_bit_integer(id_defs, dst) {
+ stateful_markers.push((dst, *src));
+ }
+ }
+ }
+ Statement::Instruction(ast::Instruction::Ld(
+ ast::LdDetails {
+ state_space: ast::LdStateSpace::Param,
+ typ: ast::LdStType::Scalar(ast::LdStScalarType::U64),
+ ..
+ },
+ arg,
+ ))
+ | Statement::Instruction(ast::Instruction::Ld(
+ ast::LdDetails {
+ state_space: ast::LdStateSpace::Param,
+ typ: ast::LdStType::Scalar(ast::LdStScalarType::S64),
+ ..
+ },
+ arg,
+ ))
+ | Statement::Instruction(ast::Instruction::Ld(
+ ast::LdDetails {
+ state_space: ast::LdStateSpace::Param,
+ typ: ast::LdStType::Scalar(ast::LdStScalarType::B64),
+ ..
+ },
+ arg,
+ )) => {
+ if let (TypedOperand::Reg(dst), Some(src)) =
+ (&arg.dst, arg.src.upcast().underlying())
+ {
+ if func_args_64bit.contains(src) {
+ multi_hash_map_append(&mut stateful_init_reg, *dst, *src);
+ }
+ }
+ }
+ _ => {}
+ }
+ }
+ let mut func_args_ptr = HashSet::new();
+ let mut regs_ptr_current = HashSet::new();
+ for (dst, src) in stateful_markers {
+ if let Some(func_args) = stateful_init_reg.get(&src) {
+ for a in func_args {
+ func_args_ptr.insert(*a);
+ regs_ptr_current.insert(src);
+ regs_ptr_current.insert(dst);
+ }
+ }
+ }
+ // BTreeSet here to have a stable order of iteration,
+ // unfortunately our tests rely on it
+ let mut regs_ptr_seen = BTreeSet::new();
+ while regs_ptr_current.len() > 0 {
+ let mut regs_ptr_new = HashSet::new();
+ for statement in func_body.iter() {
+ match statement {
+ Statement::Instruction(ast::Instruction::Add(
+ ast::ArithDetails::Unsigned(ast::UIntType::U64),
+ arg,
+ ))
+ | Statement::Instruction(ast::Instruction::Add(
+ ast::ArithDetails::Signed(ast::ArithSInt {
+ typ: ast::SIntType::S64,
+ saturate: false,
+ }),
+ arg,
+ ))
+ | Statement::Instruction(ast::Instruction::Sub(
+ ast::ArithDetails::Unsigned(ast::UIntType::U64),
+ arg,
+ ))
+ | Statement::Instruction(ast::Instruction::Sub(
+ ast::ArithDetails::Signed(ast::ArithSInt {
+ typ: ast::SIntType::S64,
+ saturate: false,
+ }),
+ arg,
+ )) => {
+ if let (TypedOperand::Reg(dst), Some(src1)) =
+ (arg.dst, arg.src1.upcast().underlying())
+ {
+ if regs_ptr_current.contains(src1) && !regs_ptr_seen.contains(src1) {
+ regs_ptr_new.insert(dst);
+ }
+ } else if let (TypedOperand::Reg(dst), Some(src2)) =
+ (arg.dst, arg.src2.upcast().underlying())
+ {
+ if regs_ptr_current.contains(src2) && !regs_ptr_seen.contains(src2) {
+ regs_ptr_new.insert(dst);
+ }
+ }
+ }
+ _ => {}
+ }
+ }
+ for id in regs_ptr_current {
+ regs_ptr_seen.insert(id);
+ }
+ regs_ptr_current = regs_ptr_new;
+ }
+ drop(regs_ptr_current);
+ let mut remapped_ids = HashMap::new();
+ let mut result = Vec::with_capacity(regs_ptr_seen.len() + func_body.len());
+ for reg in regs_ptr_seen {
+ let new_id = id_defs.new_variable(ast::Type::Pointer(
+ ast::PointerType::Scalar(ast::ScalarType::U8),
+ ast::LdStateSpace::Global,
+ ));
+ result.push(Statement::Variable(ast::Variable {
+ align: None,
+ name: new_id,
+ array_init: Vec::new(),
+ v_type: ast::VariableType::Reg(ast::VariableRegType::Pointer(
+ ast::SizedScalarType::U8,
+ ast::PointerStateSpace::Global,
+ )),
+ }));
+ remapped_ids.insert(reg, new_id);
+ }
+ for statement in func_body {
+ match statement {
+ l @ Statement::Label(_) => result.push(l),
+ c @ Statement::Conditional(_) => result.push(c),
+ Statement::Variable(var) => {
+ if !remapped_ids.contains_key(&var.name) {
+ result.push(Statement::Variable(var));
+ }
+ }
+ Statement::Instruction(ast::Instruction::Add(
+ ast::ArithDetails::Unsigned(ast::UIntType::U64),
+ arg,
+ ))
+ | Statement::Instruction(ast::Instruction::Add(
+ ast::ArithDetails::Signed(ast::ArithSInt {
+ typ: ast::SIntType::S64,
+ saturate: false,
+ }),
+ arg,
+ )) if is_add_ptr_direct(&remapped_ids, &arg) => {
+ let (ptr, offset) = match arg.src1.upcast().underlying() {
+ Some(src1) if remapped_ids.contains_key(src1) => {
+ (remapped_ids.get(src1).unwrap(), arg.src2)
+ }
+ Some(src2) if remapped_ids.contains_key(src2) => {
+ (remapped_ids.get(src2).unwrap(), arg.src1)
+ }
+ _ => return Err(error_unreachable()),
+ };
+ let dst = arg.dst.upcast().unwrap_reg()?;
+ result.push(Statement::PtrAccess(PtrAccess {
+ underlying_type: ast::PointerType::Scalar(ast::ScalarType::U8),
+ state_space: ast::LdStateSpace::Global,
+ dst: *remapped_ids.get(&dst).unwrap(),
+ ptr_src: *ptr,
+ offset_src: offset,
+ }))
+ }
+ Statement::Instruction(ast::Instruction::Sub(
+ ast::ArithDetails::Unsigned(ast::UIntType::U64),
+ arg,
+ ))
+ | Statement::Instruction(ast::Instruction::Sub(
+ ast::ArithDetails::Signed(ast::ArithSInt {
+ typ: ast::SIntType::S64,
+ saturate: false,
+ }),
+ arg,
+ )) if is_add_ptr_direct(&remapped_ids, &arg) => {
+ let (ptr, offset) = match arg.src1.upcast().underlying() {
+ Some(src1) if remapped_ids.contains_key(src1) => {
+ (remapped_ids.get(src1).unwrap(), arg.src2)
+ }
+ Some(src2) if remapped_ids.contains_key(src2) => {
+ (remapped_ids.get(src2).unwrap(), arg.src1)
+ }
+ _ => return Err(error_unreachable()),
+ };
+ let offset_neg =
+ id_defs.new_non_variable(Some(ast::Type::Scalar(ast::ScalarType::S64)));
+ result.push(Statement::Instruction(ast::Instruction::Neg(
+ ast::NegDetails {
+ typ: ast::ScalarType::S64,
+ flush_to_zero: None,
+ },
+ ast::Arg2 {
+ src: offset,
+ dst: TypedOperand::Reg(offset_neg),
+ },
+ )));
+ let dst = arg.dst.upcast().unwrap_reg()?;
+ result.push(Statement::PtrAccess(PtrAccess {
+ underlying_type: ast::PointerType::Scalar(ast::ScalarType::U8),
+ state_space: ast::LdStateSpace::Global,
+ dst: *remapped_ids.get(&dst).unwrap(),
+ ptr_src: *ptr,
+ offset_src: TypedOperand::Reg(offset_neg),
+ }))
+ }
+ Statement::Instruction(inst) => {
+ let mut post_statements = Vec::new();
+ let new_statement = inst.visit(
+ &mut |arg_desc: ArgumentDescriptor<spirv::Word>,
+ expected_type: Option<&ast::Type>| {
+ convert_to_stateful_memory_access_postprocess(
+ id_defs,
+ &remapped_ids,
+ &func_args_ptr,
+ &mut result,
+ &mut post_statements,
+ arg_desc,
+ expected_type,
+ )
+ },
+ )?;
+ result.push(new_statement);
+ result.extend(post_statements);
+ }
+ Statement::Call(call) => {
+ let mut post_statements = Vec::new();
+ let new_statement = call.visit(
+ &mut |arg_desc: ArgumentDescriptor<spirv::Word>,
+ expected_type: Option<&ast::Type>| {
+ convert_to_stateful_memory_access_postprocess(
+ id_defs,
+ &remapped_ids,
+ &func_args_ptr,
+ &mut result,
+ &mut post_statements,
+ arg_desc,
+ expected_type,
+ )
+ },
+ )?;
+ result.push(new_statement);
+ result.extend(post_statements);
+ }
+ Statement::RepackVector(pack) => {
+ let mut post_statements = Vec::new();
+ let new_statement = pack.visit(
+ &mut |arg_desc: ArgumentDescriptor<spirv::Word>,
+ expected_type: Option<&ast::Type>| {
+ convert_to_stateful_memory_access_postprocess(
+ id_defs,
+ &remapped_ids,
+ &func_args_ptr,
+ &mut result,
+ &mut post_statements,
+ arg_desc,
+ expected_type,
+ )
+ },
+ )?;
+ result.push(new_statement);
+ result.extend(post_statements);
+ }
+ _ => return Err(error_unreachable()),
+ }
+ }
+ for arg in func_args.input.iter_mut() {
+ if func_args_ptr.contains(&arg.name) {
+ arg.v_type = ast::Type::Pointer(
+ ast::PointerType::Scalar(ast::ScalarType::U8),
+ ast::LdStateSpace::Global,
+ );
+ }
+ }
+ Ok(result)
+}
+
+fn convert_to_stateful_memory_access_postprocess(
+ id_defs: &mut NumericIdResolver,
+ remapped_ids: &HashMap<spirv::Word, spirv::Word>,
+ func_args_ptr: &HashSet<spirv::Word>,
+ result: &mut Vec<TypedStatement>,
+ post_statements: &mut Vec<TypedStatement>,
+ arg_desc: ArgumentDescriptor<spirv::Word>,
+ expected_type: Option<&ast::Type>,
+) -> Result<spirv::Word, TranslateError> {
+ Ok(match remapped_ids.get(&arg_desc.op) {
+ Some(new_id) => {
+ // We skip conversion here to trigger PtrAcces in a later pass
+ let old_type = match expected_type {
+ Some(ast::Type::Pointer(_, ast::LdStateSpace::Global)) => return Ok(*new_id),
+ _ => id_defs.get_typed(arg_desc.op)?.0,
+ };
+ let old_type_clone = old_type.clone();
+ let converting_id = id_defs.new_non_variable(Some(old_type_clone));
+ if arg_desc.is_dst {
+ post_statements.push(Statement::Conversion(ImplicitConversion {
+ src: converting_id,
+ dst: *new_id,
+ from: old_type,
+ to: ast::Type::Pointer(
+ ast::PointerType::Scalar(ast::ScalarType::U8),
+ ast::LdStateSpace::Global,
+ ),
+ kind: ConversionKind::BitToPtr(ast::LdStateSpace::Global),
+ src_sema: ArgumentSemantics::Default,
+ dst_sema: arg_desc.sema,
+ }));
+ converting_id
+ } else {
+ result.push(Statement::Conversion(ImplicitConversion {
+ src: *new_id,
+ dst: converting_id,
+ from: ast::Type::Pointer(
+ ast::PointerType::Scalar(ast::ScalarType::U8),
+ ast::LdStateSpace::Global,
+ ),
+ to: old_type,
+ kind: ConversionKind::PtrToBit(ast::UIntType::U64),
+ src_sema: arg_desc.sema,
+ dst_sema: ArgumentSemantics::Default,
+ }));
+ converting_id
+ }
+ }
+ None => match func_args_ptr.get(&arg_desc.op) {
+ Some(new_id) => {
+ if arg_desc.is_dst {
+ return Err(error_unreachable());
+ }
+ // We skip conversion here to trigger PtrAcces in a later pass
+ let old_type = match expected_type {
+ Some(ast::Type::Pointer(_, ast::LdStateSpace::Global)) => return Ok(*new_id),
+ _ => id_defs.get_typed(arg_desc.op)?.0,
+ };
+ let old_type_clone = old_type.clone();
+ let converting_id = id_defs.new_non_variable(Some(old_type));
+ result.push(Statement::Conversion(ImplicitConversion {
+ src: *new_id,
+ dst: converting_id,
+ from: ast::Type::Pointer(
+ ast::PointerType::Pointer(ast::ScalarType::U8, ast::LdStateSpace::Global),
+ ast::LdStateSpace::Param,
+ ),
+ to: old_type_clone,
+ kind: ConversionKind::PtrToPtr { spirv_ptr: false },
+ src_sema: arg_desc.sema,
+ dst_sema: ArgumentSemantics::Default,
+ }));
+ converting_id
+ }
+ None => arg_desc.op,
+ },
+ })
+}
+
+fn is_add_ptr_direct(remapped_ids: &HashMap<u32, u32>, arg: &ast::Arg3<TypedArgParams>) -> bool {
+ match arg.dst {
+ TypedOperand::Imm(..) | TypedOperand::RegOffset(..) | TypedOperand::VecMember(..) => {
+ return false
+ }
+ TypedOperand::Reg(dst) => {
+ if !remapped_ids.contains_key(&dst) {
+ return false;
+ }
+ match arg.src1.upcast().underlying() {
+ Some(src1) if remapped_ids.contains_key(src1) => true,
+ Some(src2) if remapped_ids.contains_key(src2) => true,
+ _ => false,
+ }
+ }
+ }
+}
+
+fn is_64_bit_integer(id_defs: &NumericIdResolver, id: spirv::Word) -> bool {
+ match id_defs.get_typed(id) {
+ Ok((ast::Type::Scalar(ast::ScalarType::U64), _))
+ | Ok((ast::Type::Scalar(ast::ScalarType::S64), _))
+ | Ok((ast::Type::Scalar(ast::ScalarType::B64), _)) => true,
+ _ => false,
+ }
+}
+
+#[derive(Ord, PartialOrd, Eq, PartialEq, Hash, Copy, Clone)]
+enum PtxSpecialRegister {
+ Tid,
+ Tid64,
+ Ntid,
+ Ntid64,
+ Ctaid,
+ Ctaid64,
+ Nctaid,
+ Nctaid64,
+}
+
+impl PtxSpecialRegister {
+ fn try_parse(s: &str) -> Option<Self> {
+ match s {
+ "%tid" => Some(Self::Tid),
+ "%ntid" => Some(Self::Ntid),
+ "%ctaid" => Some(Self::Ctaid),
+ "%nctaid" => Some(Self::Nctaid),
+ _ => None,
+ }
+ }
+
+ fn get_type(self) -> ast::Type {
+ match self {
+ PtxSpecialRegister::Tid => ast::Type::Vector(ast::ScalarType::U32, 4),
+ PtxSpecialRegister::Tid64 => ast::Type::Vector(ast::ScalarType::U64, 3),
+ PtxSpecialRegister::Ntid => ast::Type::Vector(ast::ScalarType::U32, 4),
+ PtxSpecialRegister::Ntid64 => ast::Type::Vector(ast::ScalarType::U64, 3),
+ PtxSpecialRegister::Ctaid => ast::Type::Vector(ast::ScalarType::U32, 4),
+ PtxSpecialRegister::Ctaid64 => ast::Type::Vector(ast::ScalarType::U64, 3),
+ PtxSpecialRegister::Nctaid => ast::Type::Vector(ast::ScalarType::U32, 4),
+ PtxSpecialRegister::Nctaid64 => ast::Type::Vector(ast::ScalarType::U64, 3),
+ }
+ }
+
+ fn get_builtin(self) -> spirv::BuiltIn {
+ match self {
+ PtxSpecialRegister::Tid | PtxSpecialRegister::Tid64 => {
+ spirv::BuiltIn::LocalInvocationId
+ }
+ PtxSpecialRegister::Ntid | PtxSpecialRegister::Ntid64 => spirv::BuiltIn::WorkgroupSize,
+ PtxSpecialRegister::Ctaid | PtxSpecialRegister::Ctaid64 => spirv::BuiltIn::WorkgroupId,
+ PtxSpecialRegister::Nctaid | PtxSpecialRegister::Nctaid64 => {
+ spirv::BuiltIn::NumWorkgroups
+ }
+ }
+ }
+
+ fn normalized_sreg_and_type(self) -> Option<(PtxSpecialRegister, ast::ScalarType, u8)> {
+ match self {
+ PtxSpecialRegister::Tid => Some((PtxSpecialRegister::Tid64, ast::ScalarType::U64, 3)),
+ PtxSpecialRegister::Ntid => Some((PtxSpecialRegister::Ntid64, ast::ScalarType::U64, 3)),
+ PtxSpecialRegister::Ctaid => {
+ Some((PtxSpecialRegister::Ctaid64, ast::ScalarType::U64, 3))
+ }
+ PtxSpecialRegister::Nctaid => {
+ Some((PtxSpecialRegister::Nctaid64, ast::ScalarType::U64, 3))
+ }
+ PtxSpecialRegister::Tid64
+ | PtxSpecialRegister::Ntid64
+ | PtxSpecialRegister::Ctaid64
+ | PtxSpecialRegister::Nctaid64 => None,
+ }
+ }
+}
+
+struct SpecialRegistersMap {
+ reg_to_id: HashMap<PtxSpecialRegister, spirv::Word>,
+ id_to_reg: HashMap<spirv::Word, PtxSpecialRegister>,
+}
+
+impl SpecialRegistersMap {
+ fn new() -> Self {
+ SpecialRegistersMap {
+ reg_to_id: HashMap::new(),
+ id_to_reg: HashMap::new(),
+ }
+ }
+
+ fn builtins<'a>(&'a self) -> impl Iterator<Item = (PtxSpecialRegister, spirv::Word)> + 'a {
+ self.reg_to_id.iter().filter_map(|(sreg, id)| {
+ if sreg.normalized_sreg_and_type().is_none() {
+ Some((*sreg, *id))
+ } else {
+ None
+ }
+ })
+ }
+
+ fn interface(&self) -> Vec<spirv::Word> {
+ self.reg_to_id
+ .iter()
+ .filter_map(|(sreg, id)| {
+ if sreg.normalized_sreg_and_type().is_none() {
+ Some(*id)
+ } else {
+ None
+ }
+ })
+ .collect::<Vec<_>>()
+ }
+
+ fn get(&self, id: spirv::Word) -> Option<PtxSpecialRegister> {
+ self.id_to_reg.get(&id).copied()
+ }
+
+ fn get_or_add(&mut self, current_id: &mut spirv::Word, reg: PtxSpecialRegister) -> spirv::Word {
+ match self.reg_to_id.entry(reg) {
+ hash_map::Entry::Occupied(e) => *e.get(),
+ hash_map::Entry::Vacant(e) => {
+ let numeric_id = *current_id;
+ *current_id += 1;
+ e.insert(numeric_id);
+ self.id_to_reg.insert(numeric_id, reg);
+ numeric_id
+ }
+ }
+ }
+}
+
+struct GlobalStringIdResolver<'input> {
+ current_id: spirv::Word,
+ variables: HashMap<Cow<'input, str>, spirv::Word>,
+ variables_type_check: HashMap<u32, Option<(ast::Type, bool)>>,
+ special_registers: SpecialRegistersMap,
+ fns: HashMap<spirv::Word, FnDecl>,
+}
+
+pub struct FnDecl {
+ ret_vals: Vec<ast::FnArgumentType>,
+ params: Vec<ast::FnArgumentType>,
+}
+
+impl<'a> GlobalStringIdResolver<'a> {
+ fn new(start_id: spirv::Word) -> Self {
+ Self {
+ current_id: start_id,
+ variables: HashMap::new(),
+ variables_type_check: HashMap::new(),
+ special_registers: SpecialRegistersMap::new(),
+ fns: HashMap::new(),
+ }
+ }
+
+ fn get_or_add_def(&mut self, id: &'a str) -> spirv::Word {
+ self.get_or_add_impl(id, None)
+ }
+
+ fn get_or_add_def_typed(
+ &mut self,
+ id: &'a str,
+ typ: ast::Type,
+ is_variable: bool,
+ ) -> spirv::Word {
+ self.get_or_add_impl(id, Some((typ, is_variable)))
+ }
+
+ fn get_or_add_impl(&mut self, id: &'a str, typ: Option<(ast::Type, bool)>) -> spirv::Word {
+ let id = match self.variables.entry(Cow::Borrowed(id)) {
+ hash_map::Entry::Occupied(e) => *(e.get()),
+ hash_map::Entry::Vacant(e) => {
+ let numeric_id = self.current_id;
+ e.insert(numeric_id);
+ self.current_id += 1;
+ numeric_id
+ }
+ };
+ self.variables_type_check.insert(id, typ);
+ id
+ }
+
+ fn get_id(&self, id: &str) -> Result<spirv::Word, TranslateError> {
+ self.variables
+ .get(id)
+ .copied()
+ .ok_or(TranslateError::UnknownSymbol)
+ }
+
+ fn current_id(&self) -> spirv::Word {
+ self.current_id
+ }
+
+ fn start_fn<'b>(
+ &'b mut self,
+ header: &'b ast::MethodDecl<'a, &'a str>,
+ ) -> Result<
+ (
+ FnStringIdResolver<'a, 'b>,
+ GlobalFnDeclResolver<'a, 'b>,
+ ast::MethodDecl<'a, spirv::Word>,
+ ),
+ TranslateError,
+ > {
+ // In case a function decl was inserted earlier we want to use its id
+ let name_id = self.get_or_add_def(header.name());
+ let mut fn_resolver = FnStringIdResolver {
+ current_id: &mut self.current_id,
+ global_variables: &self.variables,
+ global_type_check: &self.variables_type_check,
+ special_registers: &mut self.special_registers,
+ variables: vec![HashMap::new(); 1],
+ type_check: HashMap::new(),
+ };
+ let new_fn_decl = match header {
+ ast::MethodDecl::Kernel { name, in_args } => ast::MethodDecl::Kernel {
+ name,
+ in_args: expand_kernel_params(&mut fn_resolver, in_args.iter())?,
+ },
+ ast::MethodDecl::Func(ret_params, _, params) => {
+ let ret_params_ids = expand_fn_params(&mut fn_resolver, ret_params.iter())?;
+ let params_ids = expand_fn_params(&mut fn_resolver, params.iter())?;
+ self.fns.insert(
+ name_id,
+ FnDecl {
+ ret_vals: ret_params_ids.iter().map(|p| p.v_type.clone()).collect(),
+ params: params_ids.iter().map(|p| p.v_type.clone()).collect(),
+ },
+ );
+ ast::MethodDecl::Func(ret_params_ids, name_id, params_ids)
+ }
+ };
+ Ok((
+ fn_resolver,
+ GlobalFnDeclResolver {
+ variables: &self.variables,
+ fns: &self.fns,
+ },
+ new_fn_decl,
+ ))
+ }
+}
+
+pub struct GlobalFnDeclResolver<'input, 'a> {
+ variables: &'a HashMap<Cow<'input, str>, spirv::Word>,
+ fns: &'a HashMap<spirv::Word, FnDecl>,
+}
+
+impl<'input, 'a> GlobalFnDeclResolver<'input, 'a> {
+ fn get_fn_decl(&self, id: spirv::Word) -> Result<&FnDecl, TranslateError> {
+ self.fns.get(&id).ok_or(TranslateError::UnknownSymbol)
+ }
+
+ fn get_fn_decl_str(&self, id: &str) -> Result<&'a FnDecl, TranslateError> {
+ match self.variables.get(id).map(|var_id| self.fns.get(var_id)) {
+ Some(Some(fn_d)) => Ok(fn_d),
+ _ => Err(TranslateError::UnknownSymbol),
+ }
+ }
+}
+
+struct FnStringIdResolver<'input, 'b> {
+ current_id: &'b mut spirv::Word,
+ global_variables: &'b HashMap<Cow<'input, str>, spirv::Word>,
+ global_type_check: &'b HashMap<u32, Option<(ast::Type, bool)>>,
+ special_registers: &'b mut SpecialRegistersMap,
+ variables: Vec<HashMap<Cow<'input, str>, spirv::Word>>,
+ type_check: HashMap<u32, Option<(ast::Type, bool)>>,
+}
+
+impl<'a, 'b> FnStringIdResolver<'a, 'b> {
+ fn finish(self) -> NumericIdResolver<'b> {
+ NumericIdResolver {
+ current_id: self.current_id,
+ global_type_check: self.global_type_check,
+ type_check: self.type_check,
+ special_registers: self.special_registers,
+ }
+ }
+
+ fn start_block(&mut self) {
+ self.variables.push(HashMap::new())
+ }
+
+ fn end_block(&mut self) {
+ self.variables.pop();
+ }
+
+ fn get_id(&mut self, id: &str) -> Result<spirv::Word, TranslateError> {
+ for scope in self.variables.iter().rev() {
+ match scope.get(id) {
+ Some(id) => return Ok(*id),
+ None => continue,
+ }
+ }
+ match self.global_variables.get(id) {
+ Some(id) => Ok(*id),
+ None => {
+ let sreg =
+ PtxSpecialRegister::try_parse(id).ok_or(TranslateError::UnknownSymbol)?;
+ Ok(self.special_registers.get_or_add(self.current_id, sreg))
+ }
+ }
+ }
+
+ fn add_def(&mut self, id: &'a str, typ: Option<ast::Type>, is_variable: bool) -> spirv::Word {
+ let numeric_id = *self.current_id;
+ self.variables
+ .last_mut()
+ .unwrap()
+ .insert(Cow::Borrowed(id), numeric_id);
+ self.type_check
+ .insert(numeric_id, typ.map(|t| (t, is_variable)));
+ *self.current_id += 1;
+ numeric_id
+ }
+
+ #[must_use]
+ fn add_defs(
+ &mut self,
+ base_id: &'a str,
+ count: u32,
+ typ: ast::Type,
+ is_variable: bool,
+ ) -> impl Iterator<Item = spirv::Word> {
+ let numeric_id = *self.current_id;
+ for i in 0..count {
+ self.variables
+ .last_mut()
+ .unwrap()
+ .insert(Cow::Owned(format!("{}{}", base_id, i)), numeric_id + i);
+ self.type_check
+ .insert(numeric_id + i, Some((typ.clone(), is_variable)));
+ }
+ *self.current_id += count;
+ (0..count).into_iter().map(move |i| i + numeric_id)
+ }
+}
+
+struct NumericIdResolver<'b> {
+ current_id: &'b mut spirv::Word,
+ global_type_check: &'b HashMap<u32, Option<(ast::Type, bool)>>,
+ type_check: HashMap<u32, Option<(ast::Type, bool)>>,
+ special_registers: &'b mut SpecialRegistersMap,
+}
+
+impl<'b> NumericIdResolver<'b> {
+ fn finish(self) -> MutableNumericIdResolver<'b> {
+ MutableNumericIdResolver { base: self }
+ }
+
+ fn get_typed(&self, id: spirv::Word) -> Result<(ast::Type, bool), TranslateError> {
+ match self.type_check.get(&id) {
+ Some(Some(x)) => Ok(x.clone()),
+ Some(None) => Err(TranslateError::UntypedSymbol),
+ None => match self.special_registers.get(id) {
+ Some(x) => Ok((x.get_type(), true)),
+ None => match self.global_type_check.get(&id) {
+ Some(Some(result)) => Ok(result.clone()),
+ Some(None) | None => Err(TranslateError::UntypedSymbol),
+ },
+ },
+ }
+ }
+
+ // This is for identifiers which will be emitted later as OpVariable
+ // They are candidates for insertion of LoadVar/StoreVar
+ fn new_variable(&mut self, typ: ast::Type) -> spirv::Word {
+ let new_id = *self.current_id;
+ self.type_check.insert(new_id, Some((typ, true)));
+ *self.current_id += 1;
+ new_id
+ }
+
+ fn new_non_variable(&mut self, typ: Option<ast::Type>) -> spirv::Word {
+ let new_id = *self.current_id;
+ self.type_check.insert(new_id, typ.map(|t| (t, false)));
+ *self.current_id += 1;
+ new_id
+ }
+}
+
+struct MutableNumericIdResolver<'b> {
+ base: NumericIdResolver<'b>,
+}
+
+impl<'b> MutableNumericIdResolver<'b> {
+ fn unmut(self) -> NumericIdResolver<'b> {
+ self.base
+ }
+
+ fn get_typed(&self, id: spirv::Word) -> Result<ast::Type, TranslateError> {
+ self.base.get_typed(id).map(|(t, _)| t)
+ }
+
+ fn new_non_variable(&mut self, typ: ast::Type) -> spirv::Word {
+ self.base.new_non_variable(Some(typ))
+ }
+}
+
+enum Statement<I, P: ast::ArgParams> {
+ Label(u32),
+ Variable(ast::Variable<ast::VariableType, P::Id>),
+ Instruction(I),
+ // SPIR-V compatible replacement for PTX predicates
+ Conditional(BrachCondition),
+ Call(ResolvedCall<P>),
+ LoadVar(LoadVarDetails),
+ StoreVar(StoreVarDetails),
+ Conversion(ImplicitConversion),
+ Constant(ConstantDefinition),
+ RetValue(ast::RetData, spirv::Word),
+ PtrAccess(PtrAccess<P>),
+ RepackVector(RepackVectorDetails),
+}
+
+impl ExpandedStatement {
+ fn map_id(self, f: &mut impl FnMut(spirv::Word, bool) -> spirv::Word) -> ExpandedStatement {
+ match self {
+ Statement::Label(id) => Statement::Label(f(id, false)),
+ Statement::Variable(mut var) => {
+ var.name = f(var.name, true);
+ Statement::Variable(var)
+ }
+ Statement::Instruction(inst) => inst
+ .visit(&mut |arg: ArgumentDescriptor<_>, _: Option<&ast::Type>| {
+ Ok(f(arg.op, arg.is_dst))
+ })
+ .unwrap(),
+ Statement::LoadVar(mut details) => {
+ details.arg.dst = f(details.arg.dst, true);
+ details.arg.src = f(details.arg.src, false);
+ Statement::LoadVar(details)
+ }
+ Statement::StoreVar(mut details) => {
+ details.arg.src1 = f(details.arg.src1, false);
+ details.arg.src2 = f(details.arg.src2, false);
+ Statement::StoreVar(details)
+ }
+ Statement::Call(mut call) => {
+ for (id, typ) in call.ret_params.iter_mut() {
+ let is_dst = match typ {
+ ast::FnArgumentType::Reg(_) => true,
+ ast::FnArgumentType::Param(_) => false,
+ ast::FnArgumentType::Shared => false,
+ };
+ *id = f(*id, is_dst);
+ }
+ call.func = f(call.func, false);
+ for (id, _) in call.param_list.iter_mut() {
+ *id = f(*id, false);
+ }
+ Statement::Call(call)
+ }
+ Statement::Conditional(mut conditional) => {
+ conditional.predicate = f(conditional.predicate, false);
+ conditional.if_true = f(conditional.if_true, false);
+ conditional.if_false = f(conditional.if_false, false);
+ Statement::Conditional(conditional)
+ }
+ Statement::Conversion(mut conv) => {
+ conv.dst = f(conv.dst, true);
+ conv.src = f(conv.src, false);
+ Statement::Conversion(conv)
+ }
+ Statement::Constant(mut constant) => {
+ constant.dst = f(constant.dst, true);
+ Statement::Constant(constant)
+ }
+ Statement::RetValue(data, id) => {
+ let id = f(id, false);
+ Statement::RetValue(data, id)
+ }
+ Statement::PtrAccess(PtrAccess {
+ underlying_type,
+ state_space,
+ dst,
+ ptr_src,
+ offset_src: constant_src,
+ }) => {
+ let dst = f(dst, true);
+ let ptr_src = f(ptr_src, false);
+ let constant_src = f(constant_src, false);
+ Statement::PtrAccess(PtrAccess {
+ underlying_type,
+ state_space,
+ dst,
+ ptr_src,
+ offset_src: constant_src,
+ })
+ }
+ Statement::RepackVector(repack) => {
+ let packed = f(repack.packed, !repack.is_extract);
+ let unpacked = repack
+ .unpacked
+ .iter()
+ .map(|id| f(*id, repack.is_extract))
+ .collect();
+ Statement::RepackVector(RepackVectorDetails {
+ packed,
+ unpacked,
+ ..repack
+ })
+ }
+ }
+ }
+}
+
+struct LoadVarDetails {
+ arg: ast::Arg2<ExpandedArgParams>,
+ typ: ast::Type,
+ // (index, vector_width)
+ // HACK ALERT
+ // For some reason IGC explodes when you try to load from builtin vectors
+ // using OpInBoundsAccessChain, the one true way to do it is to
+ // OpLoad+OpCompositeExtract
+ member_index: Option<(u8, Option<u8>)>,
+}
+
+struct StoreVarDetails {
+ arg: ast::Arg2St<ExpandedArgParams>,
+ typ: ast::Type,
+ member_index: Option<u8>,
+}
+
+struct RepackVectorDetails {
+ is_extract: bool,
+ typ: ast::ScalarType,
+ packed: spirv::Word,
+ unpacked: Vec<spirv::Word>,
+ vector_sema: ArgumentSemantics,
+}
+
+impl RepackVectorDetails {
+ fn map<
+ From: ArgParamsEx<Id = spirv::Word>,
+ To: ArgParamsEx<Id = spirv::Word>,
+ V: ArgumentMapVisitor<From, To>,
+ >(
+ self,
+ visitor: &mut V,
+ ) -> Result<RepackVectorDetails, TranslateError> {
+ let scalar = visitor.id(
+ ArgumentDescriptor {
+ op: self.packed,
+ is_dst: !self.is_extract,
+ sema: ArgumentSemantics::Default,
+ },
+ Some(&ast::Type::Vector(self.typ, self.unpacked.len() as u8)),
+ )?;
+ let scalar_type = self.typ;
+ let is_extract = self.is_extract;
+ let vector_sema = self.vector_sema;
+ let vector = self
+ .unpacked
+ .into_iter()
+ .map(|id| {
+ visitor.id(
+ ArgumentDescriptor {
+ op: id,
+ is_dst: is_extract,
+ sema: vector_sema,
+ },
+ Some(&ast::Type::Scalar(scalar_type)),
+ )
+ })
+ .collect::<Result<_, _>>()?;
+ Ok(RepackVectorDetails {
+ is_extract,
+ typ: self.typ,
+ packed: scalar,
+ unpacked: vector,
+ vector_sema,
+ })
+ }
+}
+
+impl<T: ArgParamsEx<Id = spirv::Word>, U: ArgParamsEx<Id = spirv::Word>> Visitable<T, U>
+ for RepackVectorDetails
+{
+ fn visit(
+ self,
+ visitor: &mut impl ArgumentMapVisitor<T, U>,
+ ) -> Result<Statement<ast::Instruction<U>, U>, TranslateError> {
+ Ok(Statement::RepackVector(self.map::<_, _, _>(visitor)?))
+ }
+}
+
+struct ResolvedCall<P: ast::ArgParams> {
+ pub uniform: bool,
+ pub ret_params: Vec<(P::Id, ast::FnArgumentType)>,
+ pub func: P::Id,
+ pub param_list: Vec<(P::Operand, ast::FnArgumentType)>,
+}
+
+impl<T: ast::ArgParams> ResolvedCall<T> {
+ fn cast<U: ast::ArgParams<Id = T::Id, Operand = T::Operand>>(self) -> ResolvedCall<U> {
+ ResolvedCall {
+ uniform: self.uniform,
+ ret_params: self.ret_params,
+ func: self.func,
+ param_list: self.param_list,
+ }
+ }
+}
+
+impl<From: ArgParamsEx<Id = spirv::Word>> ResolvedCall<From> {
+ fn map<To: ArgParamsEx<Id = spirv::Word>, V: ArgumentMapVisitor<From, To>>(
+ self,
+ visitor: &mut V,
+ ) -> Result<ResolvedCall<To>, TranslateError> {
+ let ret_params = self
+ .ret_params
+ .into_iter()
+ .map::<Result<_, TranslateError>, _>(|(id, typ)| {
+ let new_id = visitor.id(
+ ArgumentDescriptor {
+ op: id,
+ is_dst: !typ.is_param(),
+ sema: typ.semantics(),
+ },
+ Some(&typ.to_func_type()),
+ )?;
+ Ok((new_id, typ))
+ })
+ .collect::<Result<Vec<_>, _>>()?;
+ let func = visitor.id(
+ ArgumentDescriptor {
+ op: self.func,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ None,
+ )?;
+ let param_list = self
+ .param_list
+ .into_iter()
+ .map::<Result<_, TranslateError>, _>(|(id, typ)| {
+ let new_id = visitor.operand(
+ ArgumentDescriptor {
+ op: id,
+ is_dst: false,
+ sema: typ.semantics(),
+ },
+ &typ.to_func_type(),
+ )?;
+ Ok((new_id, typ))
+ })
+ .collect::<Result<Vec<_>, _>>()?;
+ Ok(ResolvedCall {
+ uniform: self.uniform,
+ ret_params,
+ func,
+ param_list,
+ })
+ }
+}
+
+impl<T: ArgParamsEx<Id = spirv::Word>, U: ArgParamsEx<Id = spirv::Word>> Visitable<T, U>
+ for ResolvedCall<T>
+{
+ fn visit(
+ self,
+ visitor: &mut impl ArgumentMapVisitor<T, U>,
+ ) -> Result<Statement<ast::Instruction<U>, U>, TranslateError> {
+ Ok(Statement::Call(self.map(visitor)?))
+ }
+}
+
+impl<P: ArgParamsEx<Id = spirv::Word>> PtrAccess<P> {
+ fn map<To: ArgParamsEx<Id = spirv::Word>, V: ArgumentMapVisitor<P, To>>(
+ self,
+ visitor: &mut V,
+ ) -> Result<PtrAccess<To>, TranslateError> {
+ let sema = match self.state_space {
+ ast::LdStateSpace::Const
+ | ast::LdStateSpace::Global
+ | ast::LdStateSpace::Shared
+ | ast::LdStateSpace::Generic => ArgumentSemantics::PhysicalPointer,
+ ast::LdStateSpace::Local | ast::LdStateSpace::Param => {
+ ArgumentSemantics::RegisterPointer
+ }
+ };
+ let ptr_type = ast::Type::Pointer(self.underlying_type.clone(), self.state_space);
+ let new_dst = visitor.id(
+ ArgumentDescriptor {
+ op: self.dst,
+ is_dst: true,
+ sema,
+ },
+ Some(&ptr_type),
+ )?;
+ let new_ptr_src = visitor.id(
+ ArgumentDescriptor {
+ op: self.ptr_src,
+ is_dst: false,
+ sema,
+ },
+ Some(&ptr_type),
+ )?;
+ let new_constant_src = visitor.operand(
+ ArgumentDescriptor {
+ op: self.offset_src,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ &ast::Type::Scalar(ast::ScalarType::S64),
+ )?;
+ Ok(PtrAccess {
+ underlying_type: self.underlying_type,
+ state_space: self.state_space,
+ dst: new_dst,
+ ptr_src: new_ptr_src,
+ offset_src: new_constant_src,
+ })
+ }
+}
+
+impl<T: ArgParamsEx<Id = spirv::Word>, U: ArgParamsEx<Id = spirv::Word>> Visitable<T, U>
+ for PtrAccess<T>
+{
+ fn visit(
+ self,
+ visitor: &mut impl ArgumentMapVisitor<T, U>,
+ ) -> Result<Statement<ast::Instruction<U>, U>, TranslateError> {
+ Ok(Statement::PtrAccess(self.map(visitor)?))
+ }
+}
+
+pub trait ArgParamsEx: ast::ArgParams + Sized {
+ fn get_fn_decl<'x, 'b>(
+ id: &Self::Id,
+ decl: &'b GlobalFnDeclResolver<'x, 'b>,
+ ) -> Result<&'b FnDecl, TranslateError>;
+}
+
+impl<'input> ArgParamsEx for ast::ParsedArgParams<'input> {
+ fn get_fn_decl<'x, 'b>(
+ id: &Self::Id,
+ decl: &'b GlobalFnDeclResolver<'x, 'b>,
+ ) -> Result<&'b FnDecl, TranslateError> {
+ decl.get_fn_decl_str(id)
+ }
+}
+
+enum NormalizedArgParams {}
+
+impl ast::ArgParams for NormalizedArgParams {
+ type Id = spirv::Word;
+ type Operand = ast::Operand<spirv::Word>;
+}
+
+impl ArgParamsEx for NormalizedArgParams {
+ fn get_fn_decl<'a, 'b>(
+ id: &Self::Id,
+ decl: &'b GlobalFnDeclResolver<'a, 'b>,
+ ) -> Result<&'b FnDecl, TranslateError> {
+ decl.get_fn_decl(*id)
+ }
+}
+
+type NormalizedStatement = Statement<
+ (
+ Option<ast::PredAt<spirv::Word>>,
+ ast::Instruction<NormalizedArgParams>,
+ ),
+ NormalizedArgParams,
+>;
+
+type UnconditionalStatement = Statement<ast::Instruction<NormalizedArgParams>, NormalizedArgParams>;
+
+enum TypedArgParams {}
+
+impl ast::ArgParams for TypedArgParams {
+ type Id = spirv::Word;
+ type Operand = TypedOperand;
+}
+
+impl ArgParamsEx for TypedArgParams {
+ fn get_fn_decl<'a, 'b>(
+ id: &Self::Id,
+ decl: &'b GlobalFnDeclResolver<'a, 'b>,
+ ) -> Result<&'b FnDecl, TranslateError> {
+ decl.get_fn_decl(*id)
+ }
+}
+
+#[derive(Copy, Clone)]
+enum TypedOperand {
+ Reg(spirv::Word),
+ RegOffset(spirv::Word, i32),
+ Imm(ast::ImmediateValue),
+ VecMember(spirv::Word, u8),
+}
+
+impl TypedOperand {
+ fn upcast(self) -> ast::Operand<spirv::Word> {
+ match self {
+ TypedOperand::Reg(reg) => ast::Operand::Reg(reg),
+ TypedOperand::RegOffset(reg, idx) => ast::Operand::RegOffset(reg, idx),
+ TypedOperand::Imm(x) => ast::Operand::Imm(x),
+ TypedOperand::VecMember(vec, idx) => ast::Operand::VecMember(vec, idx),
+ }
+ }
+}
+
+type TypedStatement = Statement<ast::Instruction<TypedArgParams>, TypedArgParams>;
+
+enum ExpandedArgParams {}
+type ExpandedStatement = Statement<ast::Instruction<ExpandedArgParams>, ExpandedArgParams>;
+
+impl ast::ArgParams for ExpandedArgParams {
+ type Id = spirv::Word;
+ type Operand = spirv::Word;
+}
+
+impl ArgParamsEx for ExpandedArgParams {
+ fn get_fn_decl<'a, 'b>(
+ id: &Self::Id,
+ decl: &'b GlobalFnDeclResolver<'a, 'b>,
+ ) -> Result<&'b FnDecl, TranslateError> {
+ decl.get_fn_decl(*id)
+ }
+}
+
+enum Directive<'input> {
+ Variable(ast::Variable<ast::VariableType, spirv::Word>),
+ Method(Function<'input>),
+}
+
+struct Function<'input> {
+ pub func_decl: ast::MethodDecl<'input, spirv::Word>,
+ pub spirv_decl: SpirvMethodDecl<'input>,
+ pub globals: Vec<ast::Variable<ast::VariableType, spirv::Word>>,
+ pub body: Option<Vec<ExpandedStatement>>,
+ import_as: Option<String>,
+}
+
+pub trait ArgumentMapVisitor<T: ArgParamsEx, U: ArgParamsEx> {
+ fn id(
+ &mut self,
+ desc: ArgumentDescriptor<T::Id>,
+ typ: Option<&ast::Type>,
+ ) -> Result<U::Id, TranslateError>;
+ fn operand(
+ &mut self,
+ desc: ArgumentDescriptor<T::Operand>,
+ typ: &ast::Type,
+ ) -> Result<U::Operand, TranslateError>;
+}
+
+impl<T> ArgumentMapVisitor<ExpandedArgParams, ExpandedArgParams> for T
+where
+ T: FnMut(
+ ArgumentDescriptor<spirv::Word>,
+ Option<&ast::Type>,
+ ) -> Result<spirv::Word, TranslateError>,
+{
+ fn id(
+ &mut self,
+ desc: ArgumentDescriptor<spirv::Word>,
+ t: Option<&ast::Type>,
+ ) -> Result<spirv::Word, TranslateError> {
+ self(desc, t)
+ }
+
+ fn operand(
+ &mut self,
+ desc: ArgumentDescriptor<spirv::Word>,
+ typ: &ast::Type,
+ ) -> Result<spirv::Word, TranslateError> {
+ self(desc, Some(typ))
+ }
+}
+
+impl<'a, T> ArgumentMapVisitor<ast::ParsedArgParams<'a>, NormalizedArgParams> for T
+where
+ T: FnMut(&str) -> Result<spirv::Word, TranslateError>,
+{
+ fn id(
+ &mut self,
+ desc: ArgumentDescriptor<&str>,
+ _: Option<&ast::Type>,
+ ) -> Result<spirv::Word, TranslateError> {
+ self(desc.op)
+ }
+
+ fn operand(
+ &mut self,
+ desc: ArgumentDescriptor<ast::Operand<&str>>,
+ typ: &ast::Type,
+ ) -> Result<ast::Operand<spirv::Word>, TranslateError> {
+ Ok(match desc.op {
+ ast::Operand::Reg(id) => ast::Operand::Reg(self(id)?),
+ ast::Operand::RegOffset(id, imm) => ast::Operand::RegOffset(self(id)?, imm),
+ ast::Operand::Imm(imm) => ast::Operand::Imm(imm),
+ ast::Operand::VecMember(id, member) => ast::Operand::VecMember(self(id)?, member),
+ ast::Operand::VecPack(ref ids) => ast::Operand::VecPack(
+ ids.into_iter()
+ .map(|id| self.id(desc.new_op(id), Some(typ)))
+ .collect::<Result<Vec<_>, _>>()?,
+ ),
+ })
+ }
+}
+
+pub struct ArgumentDescriptor<Op> {
+ op: Op,
+ is_dst: bool,
+ sema: ArgumentSemantics,
+}
+
+pub struct PtrAccess<P: ast::ArgParams> {
+ underlying_type: ast::PointerType,
+ state_space: ast::LdStateSpace,
+ dst: spirv::Word,
+ ptr_src: spirv::Word,
+ offset_src: P::Operand,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+pub enum ArgumentSemantics {
+ // normal register access
+ Default,
+ // normal register access with relaxed conversion rules (ld/st)
+ DefaultRelaxed,
+ // st/ld global
+ PhysicalPointer,
+ // st/ld .param, .local
+ RegisterPointer,
+ // mov of .local/.global variables
+ Address,
+}
+
+impl<T> ArgumentDescriptor<T> {
+ fn new_op<U>(&self, u: U) -> ArgumentDescriptor<U> {
+ ArgumentDescriptor {
+ op: u,
+ is_dst: self.is_dst,
+ sema: self.sema,
+ }
+ }
+}
+
+impl<T: ArgParamsEx> ast::Instruction<T> {
+ fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
+ self,
+ visitor: &mut V,
+ ) -> Result<ast::Instruction<U>, TranslateError> {
+ Ok(match self {
+ ast::Instruction::Abs(d, arg) => {
+ ast::Instruction::Abs(d, arg.map(visitor, &ast::Type::Scalar(d.typ))?)
+ }
+ // Call instruction is converted to a call statement early on
+ ast::Instruction::Call(_) => return Err(error_unreachable()),
+ ast::Instruction::Ld(d, a) => {
+ let new_args = a.map(visitor, &d)?;
+ ast::Instruction::Ld(d, new_args)
+ }
+ ast::Instruction::Mov(d, a) => {
+ let mapped = a.map(visitor, &d)?;
+ ast::Instruction::Mov(d, mapped)
+ }
+ ast::Instruction::Mul(d, a) => {
+ let inst_type = d.get_type();
+ let is_wide = d.is_wide();
+ ast::Instruction::Mul(d, a.map_non_shift(visitor, &inst_type, is_wide)?)
+ }
+ ast::Instruction::Add(d, a) => {
+ let inst_type = d.get_type();
+ ast::Instruction::Add(d, a.map_non_shift(visitor, &inst_type, false)?)
+ }
+ ast::Instruction::Setp(d, a) => {
+ let inst_type = d.typ;
+ ast::Instruction::Setp(d, a.map(visitor, &ast::Type::Scalar(inst_type))?)
+ }
+ ast::Instruction::SetpBool(d, a) => {
+ let inst_type = d.typ;
+ ast::Instruction::SetpBool(d, a.map(visitor, &ast::Type::Scalar(inst_type))?)
+ }
+ ast::Instruction::Not(t, a) => ast::Instruction::Not(t, a.map(visitor, &t.to_type())?),
+ ast::Instruction::Cvt(d, a) => {
+ let (dst_t, src_t) = match &d {
+ ast::CvtDetails::FloatFromFloat(desc) => (
+ ast::Type::Scalar(desc.dst.into()),
+ ast::Type::Scalar(desc.src.into()),
+ ),
+ ast::CvtDetails::FloatFromInt(desc) => (
+ ast::Type::Scalar(desc.dst.into()),
+ ast::Type::Scalar(desc.src.into()),
+ ),
+ ast::CvtDetails::IntFromFloat(desc) => (
+ ast::Type::Scalar(desc.dst.into()),
+ ast::Type::Scalar(desc.src.into()),
+ ),
+ ast::CvtDetails::IntFromInt(desc) => (
+ ast::Type::Scalar(desc.dst.into()),
+ ast::Type::Scalar(desc.src.into()),
+ ),
+ };
+ ast::Instruction::Cvt(d, a.map_different_types(visitor, &dst_t, &src_t)?)
+ }
+ ast::Instruction::Shl(t, a) => {
+ ast::Instruction::Shl(t, a.map_shift(visitor, &t.to_type())?)
+ }
+ ast::Instruction::Shr(t, a) => {
+ ast::Instruction::Shr(t, a.map_shift(visitor, &ast::Type::Scalar(t.into()))?)
+ }
+ ast::Instruction::St(d, a) => {
+ let new_args = a.map(visitor, &d)?;
+ ast::Instruction::St(d, new_args)
+ }
+ ast::Instruction::Bra(d, a) => ast::Instruction::Bra(d, a.map(visitor, None)?),
+ ast::Instruction::Ret(d) => ast::Instruction::Ret(d),
+ ast::Instruction::Cvta(d, a) => {
+ let inst_type = ast::Type::Scalar(ast::ScalarType::B64);
+ ast::Instruction::Cvta(d, a.map(visitor, &inst_type)?)
+ }
+ ast::Instruction::Mad(d, a) => {
+ let inst_type = d.get_type();
+ let is_wide = d.is_wide();
+ ast::Instruction::Mad(d, a.map(visitor, &inst_type, is_wide)?)
+ }
+ ast::Instruction::Or(t, a) => ast::Instruction::Or(
+ t,
+ a.map_non_shift(visitor, &ast::Type::Scalar(t.into()), false)?,
+ ),
+ ast::Instruction::Sub(d, a) => {
+ let typ = d.get_type();
+ ast::Instruction::Sub(d, a.map_non_shift(visitor, &typ, false)?)
+ }
+ ast::Instruction::Min(d, a) => {
+ let typ = d.get_type();
+ ast::Instruction::Min(d, a.map_non_shift(visitor, &typ, false)?)
+ }
+ ast::Instruction::Max(d, a) => {
+ let typ = d.get_type();
+ ast::Instruction::Max(d, a.map_non_shift(visitor, &typ, false)?)
+ }
+ ast::Instruction::Rcp(d, a) => {
+ let typ = ast::Type::Scalar(if d.is_f64 {
+ ast::ScalarType::F64
+ } else {
+ ast::ScalarType::F32
+ });
+ ast::Instruction::Rcp(d, a.map(visitor, &typ)?)
+ }
+ ast::Instruction::And(t, a) => ast::Instruction::And(
+ t,
+ a.map_non_shift(visitor, &ast::Type::Scalar(t.into()), false)?,
+ ),
+ ast::Instruction::Selp(t, a) => ast::Instruction::Selp(t, a.map_selp(visitor, t)?),
+ ast::Instruction::Bar(d, a) => ast::Instruction::Bar(d, a.map(visitor)?),
+ ast::Instruction::Atom(d, a) => {
+ ast::Instruction::Atom(d, a.map_atom(visitor, d.inner.get_type(), d.space)?)
+ }
+ ast::Instruction::AtomCas(d, a) => {
+ ast::Instruction::AtomCas(d, a.map_atom(visitor, d.typ, d.space)?)
+ }
+ ast::Instruction::Div(d, a) => {
+ ast::Instruction::Div(d, a.map_non_shift(visitor, &d.get_type(), false)?)
+ }
+ ast::Instruction::Sqrt(d, a) => {
+ ast::Instruction::Sqrt(d, a.map(visitor, &ast::Type::Scalar(d.typ.into()))?)
+ }
+ ast::Instruction::Rsqrt(d, a) => {
+ ast::Instruction::Rsqrt(d, a.map(visitor, &ast::Type::Scalar(d.typ.into()))?)
+ }
+ ast::Instruction::Neg(d, a) => {
+ ast::Instruction::Neg(d, a.map(visitor, &ast::Type::Scalar(d.typ))?)
+ }
+ ast::Instruction::Sin { flush_to_zero, arg } => {
+ let typ = ast::Type::Scalar(ast::ScalarType::F32);
+ ast::Instruction::Sin {
+ flush_to_zero,
+ arg: arg.map(visitor, &typ)?,
+ }
+ }
+ ast::Instruction::Cos { flush_to_zero, arg } => {
+ let typ = ast::Type::Scalar(ast::ScalarType::F32);
+ ast::Instruction::Cos {
+ flush_to_zero,
+ arg: arg.map(visitor, &typ)?,
+ }
+ }
+ ast::Instruction::Lg2 { flush_to_zero, arg } => {
+ let typ = ast::Type::Scalar(ast::ScalarType::F32);
+ ast::Instruction::Lg2 {
+ flush_to_zero,
+ arg: arg.map(visitor, &typ)?,
+ }
+ }
+ ast::Instruction::Ex2 { flush_to_zero, arg } => {
+ let typ = ast::Type::Scalar(ast::ScalarType::F32);
+ ast::Instruction::Ex2 {
+ flush_to_zero,
+ arg: arg.map(visitor, &typ)?,
+ }
+ }
+ ast::Instruction::Clz { typ, arg } => {
+ let dst_type = ast::Type::Scalar(ast::ScalarType::B32);
+ let src_type = ast::Type::Scalar(typ.into());
+ ast::Instruction::Clz {
+ typ,
+ arg: arg.map_different_types(visitor, &dst_type, &src_type)?,
+ }
+ }
+ ast::Instruction::Brev { typ, arg } => {
+ let full_type = ast::Type::Scalar(typ.into());
+ ast::Instruction::Brev {
+ typ,
+ arg: arg.map(visitor, &full_type)?,
+ }
+ }
+ ast::Instruction::Popc { typ, arg } => {
+ let dst_type = ast::Type::Scalar(ast::ScalarType::B32);
+ let src_type = ast::Type::Scalar(typ.into());
+ ast::Instruction::Popc {
+ typ,
+ arg: arg.map_different_types(visitor, &dst_type, &src_type)?,
+ }
+ }
+ ast::Instruction::Xor { typ, arg } => {
+ let full_type = ast::Type::Scalar(typ.into());
+ ast::Instruction::Xor {
+ typ,
+ arg: arg.map_non_shift(visitor, &full_type, false)?,
+ }
+ }
+ ast::Instruction::Bfe { typ, arg } => {
+ let full_type = ast::Type::Scalar(typ.into());
+ ast::Instruction::Bfe {
+ typ,
+ arg: arg.map_bfe(visitor, &full_type)?,
+ }
+ }
+ ast::Instruction::Rem { typ, arg } => {
+ let full_type = ast::Type::Scalar(typ.into());
+ ast::Instruction::Rem {
+ typ,
+ arg: arg.map_non_shift(visitor, &full_type, false)?,
+ }
+ }
+ })
+ }
+}
+
+impl<T: ArgParamsEx, U: ArgParamsEx> Visitable<T, U> for ast::Instruction<T> {
+ fn visit(
+ self,
+ visitor: &mut impl ArgumentMapVisitor<T, U>,
+ ) -> Result<Statement<ast::Instruction<U>, U>, TranslateError> {
+ Ok(Statement::Instruction(self.map(visitor)?))
+ }
+}
+
+impl ImplicitConversion {
+ fn map<
+ T: ArgParamsEx<Id = spirv::Word>,
+ U: ArgParamsEx<Id = spirv::Word>,
+ V: ArgumentMapVisitor<T, U>,
+ >(
+ self,
+ visitor: &mut V,
+ ) -> Result<Statement<ast::Instruction<U>, U>, TranslateError> {
+ let new_dst = visitor.id(
+ ArgumentDescriptor {
+ op: self.dst,
+ is_dst: true,
+ sema: self.dst_sema,
+ },
+ Some(&self.to),
+ )?;
+ let new_src = visitor.id(
+ ArgumentDescriptor {
+ op: self.src,
+ is_dst: false,
+ sema: self.src_sema,
+ },
+ Some(&self.from),
+ )?;
+ Ok(Statement::Conversion({
+ ImplicitConversion {
+ src: new_src,
+ dst: new_dst,
+ ..self
+ }
+ }))
+ }
+}
+
+impl<From: ArgParamsEx<Id = spirv::Word>, To: ArgParamsEx<Id = spirv::Word>> Visitable<From, To>
+ for ImplicitConversion
+{
+ fn visit(
+ self,
+ visitor: &mut impl ArgumentMapVisitor<From, To>,
+ ) -> Result<Statement<ast::Instruction<To>, To>, TranslateError> {
+ Ok(self.map(visitor)?)
+ }
+}
+
+impl<T> ArgumentMapVisitor<TypedArgParams, TypedArgParams> for T
+where
+ T: FnMut(
+ ArgumentDescriptor<spirv::Word>,
+ Option<&ast::Type>,
+ ) -> Result<spirv::Word, TranslateError>,
+{
+ fn id(
+ &mut self,
+ desc: ArgumentDescriptor<spirv::Word>,
+ t: Option<&ast::Type>,
+ ) -> Result<spirv::Word, TranslateError> {
+ self(desc, t)
+ }
+
+ fn operand(
+ &mut self,
+ desc: ArgumentDescriptor<TypedOperand>,
+ typ: &ast::Type,
+ ) -> Result<TypedOperand, TranslateError> {
+ Ok(match desc.op {
+ TypedOperand::Reg(id) => TypedOperand::Reg(self(desc.new_op(id), Some(typ))?),
+ TypedOperand::Imm(imm) => TypedOperand::Imm(imm),
+ TypedOperand::RegOffset(id, imm) => {
+ TypedOperand::RegOffset(self(desc.new_op(id), Some(typ))?, imm)
+ }
+ TypedOperand::VecMember(reg, index) => {
+ let scalar_type = match typ {
+ ast::Type::Scalar(scalar_t) => *scalar_t,
+ _ => return Err(error_unreachable()),
+ };
+ let vec_type = ast::Type::Vector(scalar_type, index + 1);
+ TypedOperand::VecMember(self(desc.new_op(reg), Some(&vec_type))?, index)
+ }
+ })
+ }
+}
+
+impl ast::Type {
+ fn widen(self) -> Result<Self, TranslateError> {
+ match self {
+ ast::Type::Scalar(scalar) => {
+ let kind = scalar.kind();
+ let width = scalar.size_of();
+ if (kind != ScalarKind::Signed
+ && kind != ScalarKind::Unsigned
+ && kind != ScalarKind::Bit)
+ || (width == 8)
+ {
+ return Err(TranslateError::MismatchedType);
+ }
+ Ok(ast::Type::Scalar(ast::ScalarType::from_parts(
+ width * 2,
+ kind,
+ )))
+ }
+ _ => Err(error_unreachable()),
+ }
+ }
+
+ fn to_parts(&self) -> TypeParts {
+ match self {
+ ast::Type::Scalar(scalar) => TypeParts {
+ kind: TypeKind::Scalar,
+ scalar_kind: scalar.kind(),
+ width: scalar.size_of(),
+ components: Vec::new(),
+ state_space: ast::LdStateSpace::Global,
+ },
+ ast::Type::Vector(scalar, components) => TypeParts {
+ kind: TypeKind::Vector,
+ scalar_kind: scalar.kind(),
+ width: scalar.size_of(),
+ components: vec![*components as u32],
+ state_space: ast::LdStateSpace::Global,
+ },
+ ast::Type::Array(scalar, components) => TypeParts {
+ kind: TypeKind::Array,
+ scalar_kind: scalar.kind(),
+ width: scalar.size_of(),
+ components: components.clone(),
+ state_space: ast::LdStateSpace::Global,
+ },
+ ast::Type::Pointer(ast::PointerType::Scalar(scalar), state_space) => TypeParts {
+ kind: TypeKind::PointerScalar,
+ scalar_kind: scalar.kind(),
+ width: scalar.size_of(),
+ components: Vec::new(),
+ state_space: *state_space,
+ },
+ ast::Type::Pointer(ast::PointerType::Vector(scalar, len), state_space) => TypeParts {
+ kind: TypeKind::PointerVector,
+ scalar_kind: scalar.kind(),
+ width: scalar.size_of(),
+ components: vec![*len as u32],
+ state_space: *state_space,
+ },
+ ast::Type::Pointer(ast::PointerType::Array(scalar, components), state_space) => {
+ TypeParts {
+ kind: TypeKind::PointerArray,
+ scalar_kind: scalar.kind(),
+ width: scalar.size_of(),
+ components: components.clone(),
+ state_space: *state_space,
+ }
+ }
+ ast::Type::Pointer(ast::PointerType::Pointer(scalar, inner_space), state_space) => {
+ TypeParts {
+ kind: TypeKind::PointerPointer,
+ scalar_kind: scalar.kind(),
+ width: scalar.size_of(),
+ components: vec![*inner_space as u32],
+ state_space: *state_space,
+ }
+ }
+ }
+ }
+
+ fn from_parts(t: TypeParts) -> Self {
+ match t.kind {
+ TypeKind::Scalar => {
+ ast::Type::Scalar(ast::ScalarType::from_parts(t.width, t.scalar_kind))
+ }
+ TypeKind::Vector => ast::Type::Vector(
+ ast::ScalarType::from_parts(t.width, t.scalar_kind),
+ t.components[0] as u8,
+ ),
+ TypeKind::Array => ast::Type::Array(
+ ast::ScalarType::from_parts(t.width, t.scalar_kind),
+ t.components,
+ ),
+ TypeKind::PointerScalar => ast::Type::Pointer(
+ ast::PointerType::Scalar(ast::ScalarType::from_parts(t.width, t.scalar_kind)),
+ t.state_space,
+ ),
+ TypeKind::PointerVector => ast::Type::Pointer(
+ ast::PointerType::Vector(
+ ast::ScalarType::from_parts(t.width, t.scalar_kind),
+ t.components[0] as u8,
+ ),
+ t.state_space,
+ ),
+ TypeKind::PointerArray => ast::Type::Pointer(
+ ast::PointerType::Array(
+ ast::ScalarType::from_parts(t.width, t.scalar_kind),
+ t.components,
+ ),
+ t.state_space,
+ ),
+ TypeKind::PointerPointer => ast::Type::Pointer(
+ ast::PointerType::Pointer(
+ ast::ScalarType::from_parts(t.width, t.scalar_kind),
+ unsafe { mem::transmute::<_, ast::LdStateSpace>(t.components[0] as u8) },
+ ),
+ t.state_space,
+ ),
+ }
+ }
+
+ fn size_of(&self) -> usize {
+ match self {
+ ast::Type::Scalar(typ) => typ.size_of() as usize,
+ ast::Type::Vector(typ, len) => (typ.size_of() as usize) * (*len as usize),
+ ast::Type::Array(typ, len) => len
+ .iter()
+ .fold(typ.size_of() as usize, |x, y| (x as usize) * (*y as usize)),
+ ast::Type::Pointer(_, _) => mem::size_of::<usize>(),
+ }
+ }
+}
+
+#[derive(Eq, PartialEq, Clone)]
+struct TypeParts {
+ kind: TypeKind,
+ scalar_kind: ScalarKind,
+ width: u8,
+ components: Vec<u32>,
+ state_space: ast::LdStateSpace,
+}
+
+#[derive(Eq, PartialEq, Copy, Clone)]
+enum TypeKind {
+ Scalar,
+ Vector,
+ Array,
+ PointerScalar,
+ PointerVector,
+ PointerArray,
+ PointerPointer,
+}
+
+impl ast::Instruction<ExpandedArgParams> {
+ fn jump_target(&self) -> Option<spirv::Word> {
+ match self {
+ ast::Instruction::Bra(_, a) => Some(a.src),
+ _ => None,
+ }
+ }
+
+ // .wide instructions don't support ftz, so it's enough to just look at the
+ // type declared by the instruction
+ fn flush_to_zero(&self) -> Option<(bool, u8)> {
+ match self {
+ ast::Instruction::Ld(_, _) => None,
+ ast::Instruction::St(_, _) => None,
+ ast::Instruction::Mov(_, _) => None,
+ ast::Instruction::Not(_, _) => None,
+ ast::Instruction::Bra(_, _) => None,
+ ast::Instruction::Shl(_, _) => None,
+ ast::Instruction::Shr(_, _) => None,
+ ast::Instruction::Ret(_) => None,
+ ast::Instruction::Call(_) => None,
+ ast::Instruction::Or(_, _) => None,
+ ast::Instruction::And(_, _) => None,
+ ast::Instruction::Cvta(_, _) => None,
+ ast::Instruction::Selp(_, _) => None,
+ ast::Instruction::Bar(_, _) => None,
+ ast::Instruction::Atom(_, _) => None,
+ ast::Instruction::AtomCas(_, _) => None,
+ ast::Instruction::Sub(ast::ArithDetails::Signed(_), _) => None,
+ ast::Instruction::Sub(ast::ArithDetails::Unsigned(_), _) => None,
+ ast::Instruction::Add(ast::ArithDetails::Signed(_), _) => None,
+ ast::Instruction::Add(ast::ArithDetails::Unsigned(_), _) => None,
+ ast::Instruction::Mul(ast::MulDetails::Unsigned(_), _) => None,
+ ast::Instruction::Mul(ast::MulDetails::Signed(_), _) => None,
+ ast::Instruction::Mad(ast::MulDetails::Unsigned(_), _) => None,
+ ast::Instruction::Mad(ast::MulDetails::Signed(_), _) => None,
+ ast::Instruction::Min(ast::MinMaxDetails::Signed(_), _) => None,
+ ast::Instruction::Min(ast::MinMaxDetails::Unsigned(_), _) => None,
+ ast::Instruction::Max(ast::MinMaxDetails::Signed(_), _) => None,
+ ast::Instruction::Max(ast::MinMaxDetails::Unsigned(_), _) => None,
+ ast::Instruction::Cvt(ast::CvtDetails::IntFromInt(_), _) => None,
+ ast::Instruction::Cvt(ast::CvtDetails::FloatFromInt(_), _) => None,
+ ast::Instruction::Div(ast::DivDetails::Unsigned(_), _) => None,
+ ast::Instruction::Div(ast::DivDetails::Signed(_), _) => None,
+ ast::Instruction::Clz { .. } => None,
+ ast::Instruction::Brev { .. } => None,
+ ast::Instruction::Popc { .. } => None,
+ ast::Instruction::Xor { .. } => None,
+ ast::Instruction::Bfe { .. } => None,
+ ast::Instruction::Rem { .. } => None,
+ ast::Instruction::Sub(ast::ArithDetails::Float(float_control), _)
+ | ast::Instruction::Add(ast::ArithDetails::Float(float_control), _)
+ | ast::Instruction::Mul(ast::MulDetails::Float(float_control), _)
+ | ast::Instruction::Mad(ast::MulDetails::Float(float_control), _) => float_control
+ .flush_to_zero
+ .map(|ftz| (ftz, ast::ScalarType::from(float_control.typ).size_of())),
+ ast::Instruction::Setp(details, _) => details
+ .flush_to_zero
+ .map(|ftz| (ftz, details.typ.size_of())),
+ ast::Instruction::SetpBool(details, _) => details
+ .flush_to_zero
+ .map(|ftz| (ftz, details.typ.size_of())),
+ ast::Instruction::Abs(details, _) => details
+ .flush_to_zero
+ .map(|ftz| (ftz, details.typ.size_of())),
+ ast::Instruction::Min(ast::MinMaxDetails::Float(float_control), _)
+ | ast::Instruction::Max(ast::MinMaxDetails::Float(float_control), _) => float_control
+ .flush_to_zero
+ .map(|ftz| (ftz, ast::ScalarType::from(float_control.typ).size_of())),
+ ast::Instruction::Rcp(details, _) => details
+ .flush_to_zero
+ .map(|ftz| (ftz, if details.is_f64 { 8 } else { 4 })),
+ // Modifier .ftz can only be specified when either .dtype or .atype
+ // is .f32 and applies only to single precision (.f32) inputs and results.
+ ast::Instruction::Cvt(
+ ast::CvtDetails::FloatFromFloat(ast::CvtDesc { flush_to_zero, .. }),
+ _,
+ )
+ | ast::Instruction::Cvt(
+ ast::CvtDetails::IntFromFloat(ast::CvtDesc { flush_to_zero, .. }),
+ _,
+ ) => flush_to_zero.map(|ftz| (ftz, 4)),
+ ast::Instruction::Div(ast::DivDetails::Float(details), _) => details
+ .flush_to_zero
+ .map(|ftz| (ftz, ast::ScalarType::from(details.typ).size_of())),
+ ast::Instruction::Sqrt(details, _) => details
+ .flush_to_zero
+ .map(|ftz| (ftz, ast::ScalarType::from(details.typ).size_of())),
+ ast::Instruction::Rsqrt(details, _) => Some((
+ details.flush_to_zero,
+ ast::ScalarType::from(details.typ).size_of(),
+ )),
+ ast::Instruction::Neg(details, _) => details
+ .flush_to_zero
+ .map(|ftz| (ftz, details.typ.size_of())),
+ ast::Instruction::Sin { flush_to_zero, .. }
+ | ast::Instruction::Cos { flush_to_zero, .. }
+ | ast::Instruction::Lg2 { flush_to_zero, .. }
+ | ast::Instruction::Ex2 { flush_to_zero, .. } => {
+ Some((*flush_to_zero, mem::size_of::<f32>() as u8))
+ }
+ }
+ }
+}
+
+type Arg2 = ast::Arg2<ExpandedArgParams>;
+type Arg2St = ast::Arg2St<ExpandedArgParams>;
+
+struct ConstantDefinition {
+ pub dst: spirv::Word,
+ pub typ: ast::ScalarType,
+ pub value: ast::ImmediateValue,
+}
+
+struct BrachCondition {
+ predicate: spirv::Word,
+ if_true: spirv::Word,
+ if_false: spirv::Word,
+}
+
+#[derive(Clone)]
+struct ImplicitConversion {
+ src: spirv::Word,
+ dst: spirv::Word,
+ from: ast::Type,
+ to: ast::Type,
+ kind: ConversionKind,
+ src_sema: ArgumentSemantics,
+ dst_sema: ArgumentSemantics,
+}
+
+#[derive(PartialEq, Copy, Clone)]
+enum ConversionKind {
+ Default,
+ // zero-extend/chop/bitcast depending on types
+ SignExtend,
+ BitToPtr(ast::LdStateSpace),
+ PtrToBit(ast::UIntType),
+ PtrToPtr { spirv_ptr: bool },
+}
+
+impl<T> ast::PredAt<T> {
+ fn map_variable<U, F: FnMut(T) -> Result<U, TranslateError>>(
+ self,
+ f: &mut F,
+ ) -> Result<ast::PredAt<U>, TranslateError> {
+ let new_label = f(self.label)?;
+ Ok(ast::PredAt {
+ not: self.not,
+ label: new_label,
+ })
+ }
+}
+
+impl<'a> ast::Instruction<ast::ParsedArgParams<'a>> {
+ fn map_variable<F: FnMut(&str) -> Result<spirv::Word, TranslateError>>(
+ self,
+ f: &mut F,
+ ) -> Result<ast::Instruction<NormalizedArgParams>, TranslateError> {
+ match self {
+ ast::Instruction::Call(call) => {
+ let call_inst = ast::CallInst {
+ uniform: call.uniform,
+ ret_params: call
+ .ret_params
+ .into_iter()
+ .map(|p| f(p))
+ .collect::<Result<_, _>>()?,
+ func: f(call.func)?,
+ param_list: call
+ .param_list
+ .into_iter()
+ .map(|p| p.map_variable(f))
+ .collect::<Result<_, _>>()?,
+ };
+ Ok(ast::Instruction::Call(call_inst))
+ }
+ i => i.map(f),
+ }
+ }
+}
+
+impl From<ast::KernelArgumentType> for ast::Type {
+ fn from(this: ast::KernelArgumentType) -> Self {
+ match this {
+ ast::KernelArgumentType::Normal(typ) => typ.into(),
+ ast::KernelArgumentType::Shared => ast::Type::Pointer(
+ ast::PointerType::Scalar(ast::ScalarType::B8),
+ ast::LdStateSpace::Shared,
+ ),
+ }
+ }
+}
+
+impl<T: ArgParamsEx> ast::Arg1<T> {
+ fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
+ self,
+ visitor: &mut V,
+ t: Option<&ast::Type>,
+ ) -> Result<ast::Arg1<U>, TranslateError> {
+ let new_src = visitor.id(
+ ArgumentDescriptor {
+ op: self.src,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ t,
+ )?;
+ Ok(ast::Arg1 { src: new_src })
+ }
+}
+
+impl<T: ArgParamsEx> ast::Arg1Bar<T> {
+ fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
+ self,
+ visitor: &mut V,
+ ) -> Result<ast::Arg1Bar<U>, TranslateError> {
+ let new_src = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ &ast::Type::Scalar(ast::ScalarType::U32),
+ )?;
+ Ok(ast::Arg1Bar { src: new_src })
+ }
+}
+
+impl<T: ArgParamsEx> ast::Arg2<T> {
+ fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
+ self,
+ visitor: &mut V,
+ t: &ast::Type,
+ ) -> Result<ast::Arg2<U>, TranslateError> {
+ let new_dst = visitor.operand(
+ ArgumentDescriptor {
+ op: self.dst,
+ is_dst: true,
+ sema: ArgumentSemantics::Default,
+ },
+ t,
+ )?;
+ let new_src = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ t,
+ )?;
+ Ok(ast::Arg2 {
+ dst: new_dst,
+ src: new_src,
+ })
+ }
+
+ fn map_different_types<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
+ self,
+ visitor: &mut V,
+ dst_t: &ast::Type,
+ src_t: &ast::Type,
+ ) -> Result<ast::Arg2<U>, TranslateError> {
+ let dst = visitor.operand(
+ ArgumentDescriptor {
+ op: self.dst,
+ is_dst: true,
+ sema: ArgumentSemantics::Default,
+ },
+ dst_t,
+ )?;
+ let src = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ src_t,
+ )?;
+ Ok(ast::Arg2 { dst, src })
+ }
+}
+
+impl<T: ArgParamsEx> ast::Arg2Ld<T> {
+ fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
+ self,
+ visitor: &mut V,
+ details: &ast::LdDetails,
+ ) -> Result<ast::Arg2Ld<U>, TranslateError> {
+ let dst = visitor.operand(
+ ArgumentDescriptor {
+ op: self.dst,
+ is_dst: true,
+ sema: ArgumentSemantics::DefaultRelaxed,
+ },
+ &ast::Type::from(details.typ.clone()),
+ )?;
+ let is_logical_ptr = details.state_space == ast::LdStateSpace::Param
+ || details.state_space == ast::LdStateSpace::Local;
+ let src = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src,
+ is_dst: false,
+ sema: if is_logical_ptr {
+ ArgumentSemantics::RegisterPointer
+ } else {
+ ArgumentSemantics::PhysicalPointer
+ },
+ },
+ &ast::Type::Pointer(
+ ast::PointerType::from(details.typ.clone()),
+ details.state_space,
+ ),
+ )?;
+ Ok(ast::Arg2Ld { dst, src })
+ }
+}
+
+impl<T: ArgParamsEx> ast::Arg2St<T> {
+ fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
+ self,
+ visitor: &mut V,
+ details: &ast::StData,
+ ) -> Result<ast::Arg2St<U>, TranslateError> {
+ let is_logical_ptr = details.state_space == ast::StStateSpace::Param
+ || details.state_space == ast::StStateSpace::Local;
+ let src1 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src1,
+ is_dst: false,
+ sema: if is_logical_ptr {
+ ArgumentSemantics::RegisterPointer
+ } else {
+ ArgumentSemantics::PhysicalPointer
+ },
+ },
+ &ast::Type::Pointer(
+ ast::PointerType::from(details.typ.clone()),
+ details.state_space.to_ld_ss(),
+ ),
+ )?;
+ let src2 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src2,
+ is_dst: false,
+ sema: ArgumentSemantics::DefaultRelaxed,
+ },
+ &details.typ.clone().into(),
+ )?;
+ Ok(ast::Arg2St { src1, src2 })
+ }
+}
+
+impl<T: ArgParamsEx> ast::Arg2Mov<T> {
+ fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
+ self,
+ visitor: &mut V,
+ details: &ast::MovDetails,
+ ) -> Result<ast::Arg2Mov<U>, TranslateError> {
+ let dst = visitor.operand(
+ ArgumentDescriptor {
+ op: self.dst,
+ is_dst: true,
+ sema: ArgumentSemantics::Default,
+ },
+ &details.typ.clone().into(),
+ )?;
+ let src = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src,
+ is_dst: false,
+ sema: if details.src_is_address {
+ ArgumentSemantics::Address
+ } else {
+ ArgumentSemantics::Default
+ },
+ },
+ &details.typ.clone().into(),
+ )?;
+ Ok(ast::Arg2Mov { dst, src })
+ }
+}
+
+impl<T: ArgParamsEx> ast::Arg3<T> {
+ fn map_non_shift<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
+ self,
+ visitor: &mut V,
+ typ: &ast::Type,
+ is_wide: bool,
+ ) -> Result<ast::Arg3<U>, TranslateError> {
+ let wide_type = if is_wide {
+ Some(typ.clone().widen()?)
+ } else {
+ None
+ };
+ let dst = visitor.operand(
+ ArgumentDescriptor {
+ op: self.dst,
+ is_dst: true,
+ sema: ArgumentSemantics::Default,
+ },
+ wide_type.as_ref().unwrap_or(typ),
+ )?;
+ let src1 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src1,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ typ,
+ )?;
+ let src2 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src2,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ typ,
+ )?;
+ Ok(ast::Arg3 { dst, src1, src2 })
+ }
+
+ fn map_shift<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
+ self,
+ visitor: &mut V,
+ t: &ast::Type,
+ ) -> Result<ast::Arg3<U>, TranslateError> {
+ let dst = visitor.operand(
+ ArgumentDescriptor {
+ op: self.dst,
+ is_dst: true,
+ sema: ArgumentSemantics::Default,
+ },
+ t,
+ )?;
+ let src1 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src1,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ t,
+ )?;
+ let src2 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src2,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ &ast::Type::Scalar(ast::ScalarType::U32),
+ )?;
+ Ok(ast::Arg3 { dst, src1, src2 })
+ }
+
+ fn map_atom<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
+ self,
+ visitor: &mut V,
+ t: ast::ScalarType,
+ state_space: ast::AtomSpace,
+ ) -> Result<ast::Arg3<U>, TranslateError> {
+ let scalar_type = ast::ScalarType::from(t);
+ let dst = visitor.operand(
+ ArgumentDescriptor {
+ op: self.dst,
+ is_dst: true,
+ sema: ArgumentSemantics::Default,
+ },
+ &ast::Type::Scalar(scalar_type),
+ )?;
+ let src1 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src1,
+ is_dst: false,
+ sema: ArgumentSemantics::PhysicalPointer,
+ },
+ &ast::Type::Pointer(
+ ast::PointerType::Scalar(scalar_type),
+ state_space.to_ld_ss(),
+ ),
+ )?;
+ let src2 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src2,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ &ast::Type::Scalar(scalar_type),
+ )?;
+ Ok(ast::Arg3 { dst, src1, src2 })
+ }
+}
+
+impl<T: ArgParamsEx> ast::Arg4<T> {
+ fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
+ self,
+ visitor: &mut V,
+ t: &ast::Type,
+ is_wide: bool,
+ ) -> Result<ast::Arg4<U>, TranslateError> {
+ let wide_type = if is_wide {
+ Some(t.clone().widen()?)
+ } else {
+ None
+ };
+ let dst = visitor.operand(
+ ArgumentDescriptor {
+ op: self.dst,
+ is_dst: true,
+ sema: ArgumentSemantics::Default,
+ },
+ wide_type.as_ref().unwrap_or(t),
+ )?;
+ let src1 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src1,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ t,
+ )?;
+ let src2 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src2,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ t,
+ )?;
+ let src3 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src3,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ t,
+ )?;
+ Ok(ast::Arg4 {
+ dst,
+ src1,
+ src2,
+ src3,
+ })
+ }
+
+ fn map_selp<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
+ self,
+ visitor: &mut V,
+ t: ast::SelpType,
+ ) -> Result<ast::Arg4<U>, TranslateError> {
+ let dst = visitor.operand(
+ ArgumentDescriptor {
+ op: self.dst,
+ is_dst: true,
+ sema: ArgumentSemantics::Default,
+ },
+ &ast::Type::Scalar(t.into()),
+ )?;
+ let src1 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src1,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ &ast::Type::Scalar(t.into()),
+ )?;
+ let src2 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src2,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ &ast::Type::Scalar(t.into()),
+ )?;
+ let src3 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src3,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ &ast::Type::Scalar(ast::ScalarType::Pred),
+ )?;
+ Ok(ast::Arg4 {
+ dst,
+ src1,
+ src2,
+ src3,
+ })
+ }
+
+ fn map_atom<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
+ self,
+ visitor: &mut V,
+ t: ast::BitType,
+ state_space: ast::AtomSpace,
+ ) -> Result<ast::Arg4<U>, TranslateError> {
+ let scalar_type = ast::ScalarType::from(t);
+ let dst = visitor.operand(
+ ArgumentDescriptor {
+ op: self.dst,
+ is_dst: true,
+ sema: ArgumentSemantics::Default,
+ },
+ &ast::Type::Scalar(scalar_type),
+ )?;
+ let src1 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src1,
+ is_dst: false,
+ sema: ArgumentSemantics::PhysicalPointer,
+ },
+ &ast::Type::Pointer(
+ ast::PointerType::Scalar(scalar_type),
+ state_space.to_ld_ss(),
+ ),
+ )?;
+ let src2 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src2,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ &ast::Type::Scalar(scalar_type),
+ )?;
+ let src3 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src3,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ &ast::Type::Scalar(scalar_type),
+ )?;
+ Ok(ast::Arg4 {
+ dst,
+ src1,
+ src2,
+ src3,
+ })
+ }
+
+ fn map_bfe<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
+ self,
+ visitor: &mut V,
+ typ: &ast::Type,
+ ) -> Result<ast::Arg4<U>, TranslateError> {
+ let dst = visitor.operand(
+ ArgumentDescriptor {
+ op: self.dst,
+ is_dst: true,
+ sema: ArgumentSemantics::Default,
+ },
+ typ,
+ )?;
+ let src1 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src1,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ typ,
+ )?;
+ let u32_type = ast::Type::Scalar(ast::ScalarType::U32);
+ let src2 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src2,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ &u32_type,
+ )?;
+ let src3 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src3,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ &u32_type,
+ )?;
+ Ok(ast::Arg4 {
+ dst,
+ src1,
+ src2,
+ src3,
+ })
+ }
+}
+
+impl<T: ArgParamsEx> ast::Arg4Setp<T> {
+ fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
+ self,
+ visitor: &mut V,
+ t: &ast::Type,
+ ) -> Result<ast::Arg4Setp<U>, TranslateError> {
+ let dst1 = visitor.id(
+ ArgumentDescriptor {
+ op: self.dst1,
+ is_dst: true,
+ sema: ArgumentSemantics::Default,
+ },
+ Some(&ast::Type::Scalar(ast::ScalarType::Pred)),
+ )?;
+ let dst2 = self
+ .dst2
+ .map(|dst2| {
+ visitor.id(
+ ArgumentDescriptor {
+ op: dst2,
+ is_dst: true,
+ sema: ArgumentSemantics::Default,
+ },
+ Some(&ast::Type::Scalar(ast::ScalarType::Pred)),
+ )
+ })
+ .transpose()?;
+ let src1 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src1,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ t,
+ )?;
+ let src2 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src2,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ t,
+ )?;
+ Ok(ast::Arg4Setp {
+ dst1,
+ dst2,
+ src1,
+ src2,
+ })
+ }
+}
+
+impl<T: ArgParamsEx> ast::Arg5Setp<T> {
+ fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
+ self,
+ visitor: &mut V,
+ t: &ast::Type,
+ ) -> Result<ast::Arg5Setp<U>, TranslateError> {
+ let dst1 = visitor.id(
+ ArgumentDescriptor {
+ op: self.dst1,
+ is_dst: true,
+ sema: ArgumentSemantics::Default,
+ },
+ Some(&ast::Type::Scalar(ast::ScalarType::Pred)),
+ )?;
+ let dst2 = self
+ .dst2
+ .map(|dst2| {
+ visitor.id(
+ ArgumentDescriptor {
+ op: dst2,
+ is_dst: true,
+ sema: ArgumentSemantics::Default,
+ },
+ Some(&ast::Type::Scalar(ast::ScalarType::Pred)),
+ )
+ })
+ .transpose()?;
+ let src1 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src1,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ t,
+ )?;
+ let src2 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src2,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ t,
+ )?;
+ let src3 = visitor.operand(
+ ArgumentDescriptor {
+ op: self.src3,
+ is_dst: false,
+ sema: ArgumentSemantics::Default,
+ },
+ &ast::Type::Scalar(ast::ScalarType::Pred),
+ )?;
+ Ok(ast::Arg5Setp {
+ dst1,
+ dst2,
+ src1,
+ src2,
+ src3,
+ })
+ }
+}
+
+impl<T> ast::Operand<T> {
+ fn map_variable<U, F: FnMut(T) -> Result<U, TranslateError>>(
+ self,
+ f: &mut F,
+ ) -> Result<ast::Operand<U>, TranslateError> {
+ Ok(match self {
+ ast::Operand::Reg(reg) => ast::Operand::Reg(f(reg)?),
+ ast::Operand::RegOffset(reg, offset) => ast::Operand::RegOffset(f(reg)?, offset),
+ ast::Operand::Imm(x) => ast::Operand::Imm(x),
+ ast::Operand::VecMember(reg, idx) => ast::Operand::VecMember(f(reg)?, idx),
+ ast::Operand::VecPack(vec) => {
+ ast::Operand::VecPack(vec.into_iter().map(f).collect::<Result<_, _>>()?)
+ }
+ })
+ }
+}
+
+impl ast::Operand<spirv::Word> {
+ fn unwrap_reg(&self) -> Result<spirv::Word, TranslateError> {
+ match self {
+ ast::Operand::Reg(reg) => Ok(*reg),
+ _ => Err(error_unreachable()),
+ }
+ }
+}
+
+impl ast::StStateSpace {
+ fn to_ld_ss(self) -> ast::LdStateSpace {
+ match self {
+ ast::StStateSpace::Generic => ast::LdStateSpace::Generic,
+ ast::StStateSpace::Global => ast::LdStateSpace::Global,
+ ast::StStateSpace::Local => ast::LdStateSpace::Local,
+ ast::StStateSpace::Param => ast::LdStateSpace::Param,
+ ast::StStateSpace::Shared => ast::LdStateSpace::Shared,
+ }
+ }
+}
+
+#[derive(Clone, Copy, PartialEq, Eq)]
+enum ScalarKind {
+ Bit,
+ Unsigned,
+ Signed,
+ Float,
+ Float2,
+ Pred,
+}
+
+impl ast::ScalarType {
+ fn kind(self) -> ScalarKind {
+ match self {
+ ast::ScalarType::U8 => ScalarKind::Unsigned,
+ ast::ScalarType::U16 => ScalarKind::Unsigned,
+ ast::ScalarType::U32 => ScalarKind::Unsigned,
+ ast::ScalarType::U64 => ScalarKind::Unsigned,
+ ast::ScalarType::S8 => ScalarKind::Signed,
+ ast::ScalarType::S16 => ScalarKind::Signed,
+ ast::ScalarType::S32 => ScalarKind::Signed,
+ ast::ScalarType::S64 => ScalarKind::Signed,
+ ast::ScalarType::B8 => ScalarKind::Bit,
+ ast::ScalarType::B16 => ScalarKind::Bit,
+ ast::ScalarType::B32 => ScalarKind::Bit,
+ ast::ScalarType::B64 => ScalarKind::Bit,
+ ast::ScalarType::F16 => ScalarKind::Float,
+ ast::ScalarType::F32 => ScalarKind::Float,
+ ast::ScalarType::F64 => ScalarKind::Float,
+ ast::ScalarType::F16x2 => ScalarKind::Float2,
+ ast::ScalarType::Pred => ScalarKind::Pred,
+ }
+ }
+
+ fn from_parts(width: u8, kind: ScalarKind) -> Self {
+ match kind {
+ ScalarKind::Float => match width {
+ 2 => ast::ScalarType::F16,
+ 4 => ast::ScalarType::F32,
+ 8 => ast::ScalarType::F64,
+ _ => unreachable!(),
+ },
+ ScalarKind::Bit => match width {
+ 1 => ast::ScalarType::B8,
+ 2 => ast::ScalarType::B16,
+ 4 => ast::ScalarType::B32,
+ 8 => ast::ScalarType::B64,
+ _ => unreachable!(),
+ },
+ ScalarKind::Signed => match width {
+ 1 => ast::ScalarType::S8,
+ 2 => ast::ScalarType::S16,
+ 4 => ast::ScalarType::S32,
+ 8 => ast::ScalarType::S64,
+ _ => unreachable!(),
+ },
+ ScalarKind::Unsigned => match width {
+ 1 => ast::ScalarType::U8,
+ 2 => ast::ScalarType::U16,
+ 4 => ast::ScalarType::U32,
+ 8 => ast::ScalarType::U64,
+ _ => unreachable!(),
+ },
+ ScalarKind::Float2 => match width {
+ 4 => ast::ScalarType::F16x2,
+ _ => unreachable!(),
+ },
+ ScalarKind::Pred => ast::ScalarType::Pred,
+ }
+ }
+}
+
+impl ast::BooleanType {
+ fn to_type(self) -> ast::Type {
+ match self {
+ ast::BooleanType::Pred => ast::Type::Scalar(ast::ScalarType::Pred),
+ ast::BooleanType::B16 => ast::Type::Scalar(ast::ScalarType::B16),
+ ast::BooleanType::B32 => ast::Type::Scalar(ast::ScalarType::B32),
+ ast::BooleanType::B64 => ast::Type::Scalar(ast::ScalarType::B64),
+ }
+ }
+}
+
+impl ast::ShlType {
+ fn to_type(self) -> ast::Type {
+ match self {
+ ast::ShlType::B16 => ast::Type::Scalar(ast::ScalarType::B16),
+ ast::ShlType::B32 => ast::Type::Scalar(ast::ScalarType::B32),
+ ast::ShlType::B64 => ast::Type::Scalar(ast::ScalarType::B64),
+ }
+ }
+}
+
+impl ast::ShrType {
+ fn signed(&self) -> bool {
+ match self {
+ ast::ShrType::S16 | ast::ShrType::S32 | ast::ShrType::S64 => true,
+ _ => false,
+ }
+ }
+}
+
+impl ast::ArithDetails {
+ fn get_type(&self) -> ast::Type {
+ ast::Type::Scalar(match self {
+ ast::ArithDetails::Unsigned(t) => (*t).into(),
+ ast::ArithDetails::Signed(d) => d.typ.into(),
+ ast::ArithDetails::Float(d) => d.typ.into(),
+ })
+ }
+}
+
+impl ast::MulDetails {
+ fn get_type(&self) -> ast::Type {
+ ast::Type::Scalar(match self {
+ ast::MulDetails::Unsigned(d) => d.typ.into(),
+ ast::MulDetails::Signed(d) => d.typ.into(),
+ ast::MulDetails::Float(d) => d.typ.into(),
+ })
+ }
+}
+
+impl ast::MinMaxDetails {
+ fn get_type(&self) -> ast::Type {
+ ast::Type::Scalar(match self {
+ ast::MinMaxDetails::Signed(t) => (*t).into(),
+ ast::MinMaxDetails::Unsigned(t) => (*t).into(),
+ ast::MinMaxDetails::Float(d) => d.typ.into(),
+ })
+ }
+}
+
+impl ast::DivDetails {
+ fn get_type(&self) -> ast::Type {
+ ast::Type::Scalar(match self {
+ ast::DivDetails::Unsigned(t) => (*t).into(),
+ ast::DivDetails::Signed(t) => (*t).into(),
+ ast::DivDetails::Float(d) => d.typ.into(),
+ })
+ }
+}
+
+impl ast::AtomInnerDetails {
+ fn get_type(&self) -> ast::ScalarType {
+ match self {
+ ast::AtomInnerDetails::Bit { typ, .. } => (*typ).into(),
+ ast::AtomInnerDetails::Unsigned { typ, .. } => (*typ).into(),
+ ast::AtomInnerDetails::Signed { typ, .. } => (*typ).into(),
+ ast::AtomInnerDetails::Float { typ, .. } => (*typ).into(),
+ }
+ }
+}
+
+impl ast::SIntType {
+ fn from_size(width: u8) -> Self {
+ match width {
+ 1 => ast::SIntType::S8,
+ 2 => ast::SIntType::S16,
+ 4 => ast::SIntType::S32,
+ 8 => ast::SIntType::S64,
+ _ => unreachable!(),
+ }
+ }
+}
+
+impl ast::UIntType {
+ fn from_size(width: u8) -> Self {
+ match width {
+ 1 => ast::UIntType::U8,
+ 2 => ast::UIntType::U16,
+ 4 => ast::UIntType::U32,
+ 8 => ast::UIntType::U64,
+ _ => unreachable!(),
+ }
+ }
+}
+
+impl ast::LdStateSpace {
+ fn to_spirv(self) -> spirv::StorageClass {
+ match self {
+ ast::LdStateSpace::Const => spirv::StorageClass::UniformConstant,
+ ast::LdStateSpace::Generic => spirv::StorageClass::Generic,
+ ast::LdStateSpace::Global => spirv::StorageClass::CrossWorkgroup,
+ ast::LdStateSpace::Local => spirv::StorageClass::Function,
+ ast::LdStateSpace::Shared => spirv::StorageClass::Workgroup,
+ ast::LdStateSpace::Param => spirv::StorageClass::Function,
+ }
+ }
+}
+
+impl From<ast::FnArgumentType> for ast::VariableType {
+ fn from(t: ast::FnArgumentType) -> Self {
+ match t {
+ ast::FnArgumentType::Reg(t) => ast::VariableType::Reg(t),
+ ast::FnArgumentType::Param(t) => ast::VariableType::Param(t),
+ ast::FnArgumentType::Shared => todo!(),
+ }
+ }
+}
+
+impl<T> ast::Operand<T> {
+ fn underlying(&self) -> Option<&T> {
+ match self {
+ ast::Operand::Reg(r) | ast::Operand::RegOffset(r, _) => Some(r),
+ ast::Operand::Imm(_) => None,
+ ast::Operand::VecMember(reg, _) => Some(reg),
+ ast::Operand::VecPack(..) => None,
+ }
+ }
+}
+
+impl ast::MulDetails {
+ fn is_wide(&self) -> bool {
+ match self {
+ ast::MulDetails::Unsigned(d) => d.control == ast::MulIntControl::Wide,
+ ast::MulDetails::Signed(d) => d.control == ast::MulIntControl::Wide,
+ ast::MulDetails::Float(_) => false,
+ }
+ }
+}
+
+impl ast::AtomSpace {
+ fn to_ld_ss(self) -> ast::LdStateSpace {
+ match self {
+ ast::AtomSpace::Generic => ast::LdStateSpace::Generic,
+ ast::AtomSpace::Global => ast::LdStateSpace::Global,
+ ast::AtomSpace::Shared => ast::LdStateSpace::Shared,
+ }
+ }
+}
+
+impl ast::MemScope {
+ fn to_spirv(self) -> spirv::Scope {
+ match self {
+ ast::MemScope::Cta => spirv::Scope::Workgroup,
+ ast::MemScope::Gpu => spirv::Scope::Device,
+ ast::MemScope::Sys => spirv::Scope::CrossDevice,
+ }
+ }
+}
+
+impl ast::AtomSemantics {
+ fn to_spirv(self) -> spirv::MemorySemantics {
+ match self {
+ ast::AtomSemantics::Relaxed => spirv::MemorySemantics::RELAXED,
+ ast::AtomSemantics::Acquire => spirv::MemorySemantics::ACQUIRE,
+ ast::AtomSemantics::Release => spirv::MemorySemantics::RELEASE,
+ ast::AtomSemantics::AcquireRelease => spirv::MemorySemantics::ACQUIRE_RELEASE,
+ }
+ }
+}
+
+impl ast::FnArgumentType {
+ fn semantics(&self) -> ArgumentSemantics {
+ match self {
+ ast::FnArgumentType::Reg(_) => ArgumentSemantics::Default,
+ ast::FnArgumentType::Param(_) => ArgumentSemantics::RegisterPointer,
+ ast::FnArgumentType::Shared => ArgumentSemantics::PhysicalPointer,
+ }
+ }
+}
+
+fn bitcast_register_pointer(
+ operand_type: &ast::Type,
+ instr_type: &ast::Type,
+ ss: Option<ast::LdStateSpace>,
+) -> Result<Option<ConversionKind>, TranslateError> {
+ bitcast_physical_pointer(operand_type, instr_type, ss)
+}
+
+fn bitcast_physical_pointer(
+ operand_type: &ast::Type,
+ instr_type: &ast::Type,
+ ss: Option<ast::LdStateSpace>,
+) -> Result<Option<ConversionKind>, TranslateError> {
+ match operand_type {
+ // array decays to a pointer
+ ast::Type::Array(op_scalar_t, _) => {
+ if let ast::Type::Pointer(instr_scalar_t, instr_space) = instr_type {
+ if ss == Some(*instr_space) {
+ if ast::Type::Scalar(*op_scalar_t) == ast::Type::from(instr_scalar_t.clone()) {
+ Ok(None)
+ } else {
+ Ok(Some(ConversionKind::PtrToPtr { spirv_ptr: false }))
+ }
+ } else {
+ if ss == Some(ast::LdStateSpace::Generic)
+ || *instr_space == ast::LdStateSpace::Generic
+ {
+ Ok(Some(ConversionKind::PtrToPtr { spirv_ptr: false }))
+ } else {
+ Err(TranslateError::MismatchedType)
+ }
+ }
+ } else {
+ Err(TranslateError::MismatchedType)
+ }
+ }
+ ast::Type::Scalar(ast::ScalarType::B64)
+ | ast::Type::Scalar(ast::ScalarType::U64)
+ | ast::Type::Scalar(ast::ScalarType::S64) => {
+ if let Some(space) = ss {
+ Ok(Some(ConversionKind::BitToPtr(space)))
+ } else {
+ Err(error_unreachable())
+ }
+ }
+ ast::Type::Scalar(ast::ScalarType::B32)
+ | ast::Type::Scalar(ast::ScalarType::U32)
+ | ast::Type::Scalar(ast::ScalarType::S32) => match ss {
+ Some(ast::LdStateSpace::Shared)
+ | Some(ast::LdStateSpace::Generic)
+ | Some(ast::LdStateSpace::Param)
+ | Some(ast::LdStateSpace::Local) => {
+ Ok(Some(ConversionKind::BitToPtr(ast::LdStateSpace::Shared)))
+ }
+ _ => Err(TranslateError::MismatchedType),
+ },
+ ast::Type::Pointer(op_scalar_t, op_space) => {
+ if let ast::Type::Pointer(instr_scalar_t, instr_space) = instr_type {
+ if op_space == instr_space {
+ if op_scalar_t == instr_scalar_t {
+ Ok(None)
+ } else {
+ Ok(Some(ConversionKind::PtrToPtr { spirv_ptr: false }))
+ }
+ } else {
+ if *op_space == ast::LdStateSpace::Generic
+ || *instr_space == ast::LdStateSpace::Generic
+ {
+ Ok(Some(ConversionKind::PtrToPtr { spirv_ptr: false }))
+ } else {
+ Err(TranslateError::MismatchedType)
+ }
+ }
+ } else {
+ Err(TranslateError::MismatchedType)
+ }
+ }
+ _ => Err(TranslateError::MismatchedType),
+ }
+}
+
+fn force_bitcast_ptr_to_bit(
+ _: &ast::Type,
+ instr_type: &ast::Type,
+ _: Option<ast::LdStateSpace>,
+) -> Result<Option<ConversionKind>, TranslateError> {
+ // TODO: verify this on f32, u16 and the like
+ if let ast::Type::Scalar(scalar_t) = instr_type {
+ if let Ok(int_type) = (*scalar_t).try_into() {
+ return Ok(Some(ConversionKind::PtrToBit(int_type)));
+ }
+ }
+ Err(TranslateError::MismatchedType)
+}
+
+fn should_bitcast(instr: &ast::Type, operand: &ast::Type) -> bool {
+ match (instr, operand) {
+ (ast::Type::Scalar(inst), ast::Type::Scalar(operand)) => {
+ if inst.size_of() != operand.size_of() {
+ return false;
+ }
+ match inst.kind() {
+ ScalarKind::Bit => operand.kind() != ScalarKind::Bit,
+ ScalarKind::Float => operand.kind() == ScalarKind::Bit,
+ ScalarKind::Signed => {
+ operand.kind() == ScalarKind::Bit || operand.kind() == ScalarKind::Unsigned
+ }
+ ScalarKind::Unsigned => {
+ operand.kind() == ScalarKind::Bit || operand.kind() == ScalarKind::Signed
+ }
+ ScalarKind::Float2 => false,
+ ScalarKind::Pred => false,
+ }
+ }
+ (ast::Type::Vector(inst, _), ast::Type::Vector(operand, _))
+ | (ast::Type::Array(inst, _), ast::Type::Array(operand, _)) => {
+ should_bitcast(&ast::Type::Scalar(*inst), &ast::Type::Scalar(*operand))
+ }
+ _ => false,
+ }
+}
+
+fn should_bitcast_packed(
+ operand: &ast::Type,
+ instr: &ast::Type,
+ ss: Option<ast::LdStateSpace>,
+) -> Result<Option<ConversionKind>, TranslateError> {
+ if let (ast::Type::Vector(vec_underlying_type, vec_len), ast::Type::Scalar(scalar)) =
+ (operand, instr)
+ {
+ if scalar.kind() == ScalarKind::Bit
+ && scalar.size_of() == (vec_underlying_type.size_of() * vec_len)
+ {
+ return Ok(Some(ConversionKind::Default));
+ }
+ }
+ should_bitcast_wrapper(operand, instr, ss)
+}
+
+fn should_bitcast_wrapper(
+ operand: &ast::Type,
+ instr: &ast::Type,
+ _: Option<ast::LdStateSpace>,
+) -> Result<Option<ConversionKind>, TranslateError> {
+ if instr == operand {
+ return Ok(None);
+ }
+ if should_bitcast(instr, operand) {
+ Ok(Some(ConversionKind::Default))
+ } else {
+ Err(TranslateError::MismatchedType)
+ }
+}
+
+fn should_convert_relaxed_src_wrapper(
+ src_type: &ast::Type,
+ instr_type: &ast::Type,
+ _: Option<ast::LdStateSpace>,
+) -> Result<Option<ConversionKind>, TranslateError> {
+ if src_type == instr_type {
+ return Ok(None);
+ }
+ match should_convert_relaxed_src(src_type, instr_type) {
+ conv @ Some(_) => Ok(conv),
+ None => Err(TranslateError::MismatchedType),
+ }
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#operand-size-exceeding-instruction-type-size__relaxed-type-checking-rules-source-operands
+fn should_convert_relaxed_src(
+ src_type: &ast::Type,
+ instr_type: &ast::Type,
+) -> Option<ConversionKind> {
+ if src_type == instr_type {
+ return None;
+ }
+ match (src_type, instr_type) {
+ (ast::Type::Scalar(src_type), ast::Type::Scalar(instr_type)) => match instr_type.kind() {
+ ScalarKind::Bit => {
+ if instr_type.size_of() <= src_type.size_of() {
+ Some(ConversionKind::Default)
+ } else {
+ None
+ }
+ }
+ ScalarKind::Signed | ScalarKind::Unsigned => {
+ if instr_type.size_of() <= src_type.size_of()
+ && src_type.kind() != ScalarKind::Float
+ {
+ Some(ConversionKind::Default)
+ } else {
+ None
+ }
+ }
+ ScalarKind::Float => {
+ if instr_type.size_of() <= src_type.size_of() && src_type.kind() == ScalarKind::Bit
+ {
+ Some(ConversionKind::Default)
+ } else {
+ None
+ }
+ }
+ ScalarKind::Float2 => todo!(),
+ ScalarKind::Pred => None,
+ },
+ (ast::Type::Vector(dst_type, _), ast::Type::Vector(instr_type, _))
+ | (ast::Type::Array(dst_type, _), ast::Type::Array(instr_type, _)) => {
+ should_convert_relaxed_src(
+ &ast::Type::Scalar(*dst_type),
+ &ast::Type::Scalar(*instr_type),
+ )
+ }
+ _ => None,
+ }
+}
+
+fn should_convert_relaxed_dst_wrapper(
+ dst_type: &ast::Type,
+ instr_type: &ast::Type,
+ _: Option<ast::LdStateSpace>,
+) -> Result<Option<ConversionKind>, TranslateError> {
+ if dst_type == instr_type {
+ return Ok(None);
+ }
+ match should_convert_relaxed_dst(dst_type, instr_type) {
+ conv @ Some(_) => Ok(conv),
+ None => Err(TranslateError::MismatchedType),
+ }
+}
+
+// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#operand-size-exceeding-instruction-type-size__relaxed-type-checking-rules-destination-operands
+fn should_convert_relaxed_dst(
+ dst_type: &ast::Type,
+ instr_type: &ast::Type,
+) -> Option<ConversionKind> {
+ if dst_type == instr_type {
+ return None;
+ }
+ match (dst_type, instr_type) {
+ (ast::Type::Scalar(dst_type), ast::Type::Scalar(instr_type)) => match instr_type.kind() {
+ ScalarKind::Bit => {
+ if instr_type.size_of() <= dst_type.size_of() {
+ Some(ConversionKind::Default)
+ } else {
+ None
+ }
+ }
+ ScalarKind::Signed => {
+ if dst_type.kind() != ScalarKind::Float {
+ if instr_type.size_of() == dst_type.size_of() {
+ Some(ConversionKind::Default)
+ } else if instr_type.size_of() < dst_type.size_of() {
+ Some(ConversionKind::SignExtend)
+ } else {
+ None
+ }
+ } else {
+ None
+ }
+ }
+ ScalarKind::Unsigned => {
+ if instr_type.size_of() <= dst_type.size_of()
+ && dst_type.kind() != ScalarKind::Float
+ {
+ Some(ConversionKind::Default)
+ } else {
+ None
+ }
+ }
+ ScalarKind::Float => {
+ if instr_type.size_of() <= dst_type.size_of() && dst_type.kind() == ScalarKind::Bit
+ {
+ Some(ConversionKind::Default)
+ } else {
+ None
+ }
+ }
+ ScalarKind::Float2 => todo!(),
+ ScalarKind::Pred => None,
+ },
+ (ast::Type::Vector(dst_type, _), ast::Type::Vector(instr_type, _))
+ | (ast::Type::Array(dst_type, _), ast::Type::Array(instr_type, _)) => {
+ should_convert_relaxed_dst(
+ &ast::Type::Scalar(*dst_type),
+ &ast::Type::Scalar(*instr_type),
+ )
+ }
+ _ => None,
+ }
+}
+
+impl<'a> ast::MethodDecl<'a, &'a str> {
+ fn name(&self) -> &'a str {
+ match self {
+ ast::MethodDecl::Kernel { name, .. } => name,
+ ast::MethodDecl::Func(_, name, _) => name,
+ }
+ }
+}
+
+struct SpirvMethodDecl<'input> {
+ input: Vec<ast::Variable<ast::Type, spirv::Word>>,
+ output: Vec<ast::Variable<ast::Type, spirv::Word>>,
+ name: MethodName<'input>,
+ uses_shared_mem: bool,
+}
+
+impl<'input> SpirvMethodDecl<'input> {
+ fn new(ast_decl: &ast::MethodDecl<'input, spirv::Word>) -> Self {
+ let (input, output) = match ast_decl {
+ ast::MethodDecl::Kernel { in_args, .. } => {
+ let spirv_input = in_args
+ .iter()
+ .map(|var| {
+ let v_type = match &var.v_type {
+ ast::KernelArgumentType::Normal(t) => {
+ ast::FnArgumentType::Param(t.clone())
+ }
+ ast::KernelArgumentType::Shared => ast::FnArgumentType::Shared,
+ };
+ ast::Variable {
+ name: var.name,
+ align: var.align,
+ v_type: v_type.to_kernel_type(),
+ array_init: var.array_init.clone(),
+ }
+ })
+ .collect();
+ (spirv_input, Vec::new())
+ }
+ ast::MethodDecl::Func(out_args, _, in_args) => {
+ let (param_output, non_param_output): (Vec<_>, Vec<_>) =
+ out_args.iter().partition(|var| var.v_type.is_param());
+ let spirv_output = non_param_output
+ .into_iter()
+ .cloned()
+ .map(|var| ast::Variable {
+ name: var.name,
+ align: var.align,
+ v_type: var.v_type.to_func_type(),
+ array_init: var.array_init.clone(),
+ })
+ .collect();
+ let spirv_input = param_output
+ .into_iter()
+ .cloned()
+ .chain(in_args.iter().cloned())
+ .map(|var| ast::Variable {
+ name: var.name,
+ align: var.align,
+ v_type: var.v_type.to_func_type(),
+ array_init: var.array_init.clone(),
+ })
+ .collect();
+ (spirv_input, spirv_output)
+ }
+ };
+ SpirvMethodDecl {
+ input,
+ output,
+ name: MethodName::new(ast_decl),
+ uses_shared_mem: false,
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::ast;
+
+ static SCALAR_TYPES: [ast::ScalarType; 15] = [
+ ast::ScalarType::B8,
+ ast::ScalarType::B16,
+ ast::ScalarType::B32,
+ ast::ScalarType::B64,
+ ast::ScalarType::S8,
+ ast::ScalarType::S16,
+ ast::ScalarType::S32,
+ ast::ScalarType::S64,
+ ast::ScalarType::U8,
+ ast::ScalarType::U16,
+ ast::ScalarType::U32,
+ ast::ScalarType::U64,
+ ast::ScalarType::F16,
+ ast::ScalarType::F32,
+ ast::ScalarType::F64,
+ ];
+
+ static RELAXED_SRC_CONVERSION_TABLE: &'static str =
+ "b8 - chop chop chop - chop chop chop - chop chop chop chop chop chop
+ b16 inv - chop chop inv - chop chop inv - chop chop - chop chop
+ b32 inv inv - chop inv inv - chop inv inv - chop inv - chop
+ b64 inv inv inv - inv inv inv - inv inv inv - inv inv -
+ s8 - chop chop chop - chop chop chop - chop chop chop inv inv inv
+ s16 inv - chop chop inv - chop chop inv - chop chop inv inv inv
+ s32 inv inv - chop inv inv - chop inv inv - chop inv inv inv
+ s64 inv inv inv - inv inv inv - inv inv inv - inv inv inv
+ u8 - chop chop chop - chop chop chop - chop chop chop inv inv inv
+ u16 inv - chop chop inv - chop chop inv - chop chop inv inv inv
+ u32 inv inv - chop inv inv - chop inv inv - chop inv inv inv
+ u64 inv inv inv - inv inv inv - inv inv inv - inv inv inv
+ f16 inv - chop chop inv inv inv inv inv inv inv inv - inv inv
+ f32 inv inv - chop inv inv inv inv inv inv inv inv inv - inv
+ f64 inv inv inv - inv inv inv inv inv inv inv inv inv inv -";
+
+ static RELAXED_DST_CONVERSION_TABLE: &'static str =
+ "b8 - zext zext zext - zext zext zext - zext zext zext zext zext zext
+ b16 inv - zext zext inv - zext zext inv - zext zext - zext zext
+ b32 inv inv - zext inv inv - zext inv inv - zext inv - zext
+ b64 inv inv inv - inv inv inv - inv inv inv - inv inv -
+ s8 - sext sext sext - sext sext sext - sext sext sext inv inv inv
+ s16 inv - sext sext inv - sext sext inv - sext sext inv inv inv
+ s32 inv inv - sext inv inv - sext inv inv - sext inv inv inv
+ s64 inv inv inv - inv inv inv - inv inv inv - inv inv inv
+ u8 - zext zext zext - zext zext zext - zext zext zext inv inv inv
+ u16 inv - zext zext inv - zext zext inv - zext zext inv inv inv
+ u32 inv inv - zext inv inv - zext inv inv - zext inv inv inv
+ u64 inv inv inv - inv inv inv - inv inv inv - inv inv inv
+ f16 inv - zext zext inv inv inv inv inv inv inv inv - inv inv
+ f32 inv inv - zext inv inv inv inv inv inv inv inv inv - inv
+ f64 inv inv inv - inv inv inv inv inv inv inv inv inv inv -";
+
+ fn table_entry_to_conversion(entry: &'static str) -> Option<ConversionKind> {
+ match entry {
+ "-" => Some(ConversionKind::Default),
+ "inv" => None,
+ "zext" => Some(ConversionKind::Default),
+ "chop" => Some(ConversionKind::Default),
+ "sext" => Some(ConversionKind::SignExtend),
+ _ => unreachable!(),
+ }
+ }
+
+ fn parse_conversion_table(table: &'static str) -> Vec<Vec<Option<ConversionKind>>> {
+ table
+ .lines()
+ .map(|line| {
+ line.split_ascii_whitespace()
+ .skip(1)
+ .map(table_entry_to_conversion)
+ .collect::<Vec<_>>()
+ })
+ .collect::<Vec<_>>()
+ }
+
+ fn assert_conversion_table<F: Fn(&ast::Type, &ast::Type) -> Option<ConversionKind>>(
+ table: &'static str,
+ f: F,
+ ) {
+ let conv_table = parse_conversion_table(table);
+ for (instr_idx, instr_type) in SCALAR_TYPES.iter().enumerate() {
+ for (op_idx, op_type) in SCALAR_TYPES.iter().enumerate() {
+ let conversion = f(
+ &ast::Type::Scalar(*op_type),
+ &ast::Type::Scalar(*instr_type),
+ );
+ if instr_idx == op_idx {
+ assert!(conversion == None);
+ } else {
+ assert!(conversion == conv_table[instr_idx][op_idx]);
+ }
+ }
+ }
+ }
+
+ #[test]
+ fn should_convert_relaxed_src_all_combinations() {
+ assert_conversion_table(RELAXED_SRC_CONVERSION_TABLE, should_convert_relaxed_src);
+ }
+
+ #[test]
+ fn should_convert_relaxed_dst_all_combinations() {
+ assert_conversion_table(RELAXED_DST_CONVERSION_TABLE, should_convert_relaxed_dst);
+ }
+}
diff --git a/spirv_tools-sys/Cargo.toml b/spirv_tools-sys/Cargo.toml
new file mode 100644
index 0000000..a5cadc1
--- /dev/null
+++ b/spirv_tools-sys/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "spirv_tools-sys"
+version = "0.0.0"
+authors = ["Andrzej Janik <[email protected]>"]
+edition = "2018"
+
+[lib]
+
+[build-dependencies]
+cmake = "0.1" \ No newline at end of file
diff --git a/spirv_tools-sys/README b/spirv_tools-sys/README
new file mode 100644
index 0000000..3152164
--- /dev/null
+++ b/spirv_tools-sys/README
@@ -0,0 +1 @@
+bindgen --whitelist-type="spv.*" --whitelist-function="spv.*" --size_t-is-usize --default-enum-style=rust --bitfield-enum="spv_text_to_binary_options_t|spv_binary_to_text_options_t" ../ext/SPIRV-Tools/include/spirv-tools/libspirv.h -o src/spirv_tools.rs \ No newline at end of file
diff --git a/spirv_tools-sys/build.rs b/spirv_tools-sys/build.rs
new file mode 100644
index 0000000..ae72561
--- /dev/null
+++ b/spirv_tools-sys/build.rs
@@ -0,0 +1,28 @@
+extern crate cmake;
+
+use cmake::Config;
+use std::{env::VarError, path::PathBuf};
+
+fn main() -> Result<(), VarError> {
+ let root_path = std::env::var("CARGO_MANIFEST_DIR")?;
+ let mut headers_path = PathBuf::new();
+ headers_path.push(root_path);
+ headers_path.push("../ext/spirv-headers");
+ let spirv_tools_dir = Config::new("../ext/spirv-tools")
+ .always_configure(false)
+ .define("SPIRV-Headers_SOURCE_DIR", headers_path)
+ .define("SPIRV_SKIP_EXECUTABLES", "ON")
+ .define("SPIRV_SKIP_TESTS", "ON")
+ .build();
+ println!(
+ "cargo:rustc-link-search=native={}/bin",
+ spirv_tools_dir.display()
+ );
+ println!(
+ "cargo:rustc-link-search=native={}/lib",
+ spirv_tools_dir.display()
+ );
+ // dynamic linking to avoid linking to C++ runtime
+ println!("cargo:rustc-link-lib=dylib=SPIRV-Tools-shared");
+ Ok(())
+}
diff --git a/spirv_tools-sys/src/lib.rs b/spirv_tools-sys/src/lib.rs
new file mode 100644
index 0000000..c1a9dc2
--- /dev/null
+++ b/spirv_tools-sys/src/lib.rs
@@ -0,0 +1,3 @@
+#[allow(warnings)]
+mod spirv_tools;
+pub use spirv_tools::*; \ No newline at end of file
diff --git a/spirv_tools-sys/src/spirv_tools.rs b/spirv_tools-sys/src/spirv_tools.rs
new file mode 100644
index 0000000..fe9640b
--- /dev/null
+++ b/spirv_tools-sys/src/spirv_tools.rs
@@ -0,0 +1,972 @@
+/* automatically generated by rust-bindgen 0.54.1 */
+
+pub type __uint16_t = ::std::os::raw::c_ushort;
+pub type __uint32_t = ::std::os::raw::c_uint;
+#[repr(i32)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum spv_result_t {
+ SPV_SUCCESS = 0,
+ SPV_UNSUPPORTED = 1,
+ SPV_END_OF_STREAM = 2,
+ SPV_WARNING = 3,
+ SPV_FAILED_MATCH = 4,
+ SPV_REQUESTED_TERMINATION = 5,
+ SPV_ERROR_INTERNAL = -1,
+ SPV_ERROR_OUT_OF_MEMORY = -2,
+ SPV_ERROR_INVALID_POINTER = -3,
+ SPV_ERROR_INVALID_BINARY = -4,
+ SPV_ERROR_INVALID_TEXT = -5,
+ SPV_ERROR_INVALID_TABLE = -6,
+ SPV_ERROR_INVALID_VALUE = -7,
+ SPV_ERROR_INVALID_DIAGNOSTIC = -8,
+ SPV_ERROR_INVALID_LOOKUP = -9,
+ SPV_ERROR_INVALID_ID = -10,
+ SPV_ERROR_INVALID_CFG = -11,
+ SPV_ERROR_INVALID_LAYOUT = -12,
+ SPV_ERROR_INVALID_CAPABILITY = -13,
+ SPV_ERROR_INVALID_DATA = -14,
+ SPV_ERROR_MISSING_EXTENSION = -15,
+ SPV_ERROR_WRONG_VERSION = -16,
+ _spv_result_t = 2147483647,
+}
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum spv_message_level_t {
+ SPV_MSG_FATAL = 0,
+ SPV_MSG_INTERNAL_ERROR = 1,
+ SPV_MSG_ERROR = 2,
+ SPV_MSG_WARNING = 3,
+ SPV_MSG_INFO = 4,
+ SPV_MSG_DEBUG = 5,
+}
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum spv_endianness_t {
+ SPV_ENDIANNESS_LITTLE = 0,
+ SPV_ENDIANNESS_BIG = 1,
+ _spv_endianness_t = 2147483647,
+}
+impl spv_operand_type_t {
+ pub const SPV_OPERAND_TYPE_FIRST_OPTIONAL_TYPE: spv_operand_type_t =
+ spv_operand_type_t::SPV_OPERAND_TYPE_OPTIONAL_ID;
+}
+impl spv_operand_type_t {
+ pub const SPV_OPERAND_TYPE_FIRST_VARIABLE_TYPE: spv_operand_type_t =
+ spv_operand_type_t::SPV_OPERAND_TYPE_VARIABLE_ID;
+}
+impl spv_operand_type_t {
+ pub const SPV_OPERAND_TYPE_LAST_VARIABLE_TYPE: spv_operand_type_t =
+ spv_operand_type_t::SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER;
+}
+impl spv_operand_type_t {
+ pub const SPV_OPERAND_TYPE_LAST_OPTIONAL_TYPE: spv_operand_type_t =
+ spv_operand_type_t::SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER;
+}
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum spv_operand_type_t {
+ SPV_OPERAND_TYPE_NONE = 0,
+ SPV_OPERAND_TYPE_ID = 1,
+ SPV_OPERAND_TYPE_TYPE_ID = 2,
+ SPV_OPERAND_TYPE_RESULT_ID = 3,
+ SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID = 4,
+ SPV_OPERAND_TYPE_SCOPE_ID = 5,
+ SPV_OPERAND_TYPE_LITERAL_INTEGER = 6,
+ SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER = 7,
+ SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER = 8,
+ SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER = 9,
+ SPV_OPERAND_TYPE_LITERAL_STRING = 10,
+ SPV_OPERAND_TYPE_SOURCE_LANGUAGE = 11,
+ SPV_OPERAND_TYPE_EXECUTION_MODEL = 12,
+ SPV_OPERAND_TYPE_ADDRESSING_MODEL = 13,
+ SPV_OPERAND_TYPE_MEMORY_MODEL = 14,
+ SPV_OPERAND_TYPE_EXECUTION_MODE = 15,
+ SPV_OPERAND_TYPE_STORAGE_CLASS = 16,
+ SPV_OPERAND_TYPE_DIMENSIONALITY = 17,
+ SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE = 18,
+ SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE = 19,
+ SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT = 20,
+ SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER = 21,
+ SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE = 22,
+ SPV_OPERAND_TYPE_FP_ROUNDING_MODE = 23,
+ SPV_OPERAND_TYPE_LINKAGE_TYPE = 24,
+ SPV_OPERAND_TYPE_ACCESS_QUALIFIER = 25,
+ SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE = 26,
+ SPV_OPERAND_TYPE_DECORATION = 27,
+ SPV_OPERAND_TYPE_BUILT_IN = 28,
+ SPV_OPERAND_TYPE_GROUP_OPERATION = 29,
+ SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS = 30,
+ SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO = 31,
+ SPV_OPERAND_TYPE_CAPABILITY = 32,
+ SPV_OPERAND_TYPE_RAY_FLAGS = 33,
+ SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION = 34,
+ SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE = 35,
+ SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE = 36,
+ SPV_OPERAND_TYPE_IMAGE = 37,
+ SPV_OPERAND_TYPE_FP_FAST_MATH_MODE = 38,
+ SPV_OPERAND_TYPE_SELECTION_CONTROL = 39,
+ SPV_OPERAND_TYPE_LOOP_CONTROL = 40,
+ SPV_OPERAND_TYPE_FUNCTION_CONTROL = 41,
+ SPV_OPERAND_TYPE_MEMORY_ACCESS = 42,
+ SPV_OPERAND_TYPE_OPTIONAL_ID = 43,
+ SPV_OPERAND_TYPE_OPTIONAL_IMAGE = 44,
+ SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS = 45,
+ SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER = 46,
+ SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER = 47,
+ SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER = 48,
+ SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING = 49,
+ SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER = 50,
+ SPV_OPERAND_TYPE_OPTIONAL_CIV = 51,
+ SPV_OPERAND_TYPE_VARIABLE_ID = 52,
+ SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER = 53,
+ SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID = 54,
+ SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER = 55,
+ SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS = 56,
+ SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING = 57,
+ SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE = 58,
+ SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER = 59,
+ SPV_OPERAND_TYPE_DEBUG_OPERATION = 60,
+ SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS = 61,
+ SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING = 62,
+ SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE = 63,
+ SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER = 64,
+ SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION = 65,
+ SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY = 66,
+ SPV_OPERAND_TYPE_NUM_OPERAND_TYPES = 67,
+ _spv_operand_type_t = 2147483647,
+}
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum spv_ext_inst_type_t {
+ SPV_EXT_INST_TYPE_NONE = 0,
+ SPV_EXT_INST_TYPE_GLSL_STD_450 = 1,
+ SPV_EXT_INST_TYPE_OPENCL_STD = 2,
+ SPV_EXT_INST_TYPE_SPV_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER = 3,
+ SPV_EXT_INST_TYPE_SPV_AMD_SHADER_TRINARY_MINMAX = 4,
+ SPV_EXT_INST_TYPE_SPV_AMD_GCN_SHADER = 5,
+ SPV_EXT_INST_TYPE_SPV_AMD_SHADER_BALLOT = 6,
+ SPV_EXT_INST_TYPE_DEBUGINFO = 7,
+ SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 = 8,
+ SPV_EXT_INST_TYPE_NONSEMANTIC_UNKNOWN = 9,
+ _spv_ext_inst_type_t = 2147483647,
+}
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum spv_number_kind_t {
+ SPV_NUMBER_NONE = 0,
+ SPV_NUMBER_UNSIGNED_INT = 1,
+ SPV_NUMBER_SIGNED_INT = 2,
+ SPV_NUMBER_FLOATING = 3,
+}
+impl spv_text_to_binary_options_t {
+ pub const SPV_TEXT_TO_BINARY_OPTION_NONE: spv_text_to_binary_options_t =
+ spv_text_to_binary_options_t(1);
+}
+impl spv_text_to_binary_options_t {
+ pub const SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS: spv_text_to_binary_options_t =
+ spv_text_to_binary_options_t(2);
+}
+impl spv_text_to_binary_options_t {
+ pub const _spv_text_to_binary_options_t: spv_text_to_binary_options_t =
+ spv_text_to_binary_options_t(2147483647);
+}
+impl ::std::ops::BitOr<spv_text_to_binary_options_t> for spv_text_to_binary_options_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ spv_text_to_binary_options_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for spv_text_to_binary_options_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: spv_text_to_binary_options_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<spv_text_to_binary_options_t> for spv_text_to_binary_options_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ spv_text_to_binary_options_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for spv_text_to_binary_options_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: spv_text_to_binary_options_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct spv_text_to_binary_options_t(pub u32);
+impl spv_binary_to_text_options_t {
+ pub const SPV_BINARY_TO_TEXT_OPTION_NONE: spv_binary_to_text_options_t =
+ spv_binary_to_text_options_t(1);
+}
+impl spv_binary_to_text_options_t {
+ pub const SPV_BINARY_TO_TEXT_OPTION_PRINT: spv_binary_to_text_options_t =
+ spv_binary_to_text_options_t(2);
+}
+impl spv_binary_to_text_options_t {
+ pub const SPV_BINARY_TO_TEXT_OPTION_COLOR: spv_binary_to_text_options_t =
+ spv_binary_to_text_options_t(4);
+}
+impl spv_binary_to_text_options_t {
+ pub const SPV_BINARY_TO_TEXT_OPTION_INDENT: spv_binary_to_text_options_t =
+ spv_binary_to_text_options_t(8);
+}
+impl spv_binary_to_text_options_t {
+ pub const SPV_BINARY_TO_TEXT_OPTION_SHOW_BYTE_OFFSET: spv_binary_to_text_options_t =
+ spv_binary_to_text_options_t(16);
+}
+impl spv_binary_to_text_options_t {
+ pub const SPV_BINARY_TO_TEXT_OPTION_NO_HEADER: spv_binary_to_text_options_t =
+ spv_binary_to_text_options_t(32);
+}
+impl spv_binary_to_text_options_t {
+ pub const SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES: spv_binary_to_text_options_t =
+ spv_binary_to_text_options_t(64);
+}
+impl spv_binary_to_text_options_t {
+ pub const _spv_binary_to_text_options_t: spv_binary_to_text_options_t =
+ spv_binary_to_text_options_t(2147483647);
+}
+impl ::std::ops::BitOr<spv_binary_to_text_options_t> for spv_binary_to_text_options_t {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, other: Self) -> Self {
+ spv_binary_to_text_options_t(self.0 | other.0)
+ }
+}
+impl ::std::ops::BitOrAssign for spv_binary_to_text_options_t {
+ #[inline]
+ fn bitor_assign(&mut self, rhs: spv_binary_to_text_options_t) {
+ self.0 |= rhs.0;
+ }
+}
+impl ::std::ops::BitAnd<spv_binary_to_text_options_t> for spv_binary_to_text_options_t {
+ type Output = Self;
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ spv_binary_to_text_options_t(self.0 & other.0)
+ }
+}
+impl ::std::ops::BitAndAssign for spv_binary_to_text_options_t {
+ #[inline]
+ fn bitand_assign(&mut self, rhs: spv_binary_to_text_options_t) {
+ self.0 &= rhs.0;
+ }
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct spv_binary_to_text_options_t(pub u32);
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct spv_parsed_operand_t {
+ pub offset: u16,
+ pub num_words: u16,
+ pub type_: spv_operand_type_t,
+ pub number_kind: spv_number_kind_t,
+ pub number_bit_width: u32,
+}
+#[test]
+fn bindgen_test_layout_spv_parsed_operand_t() {
+ assert_eq!(
+ ::std::mem::size_of::<spv_parsed_operand_t>(),
+ 16usize,
+ concat!("Size of: ", stringify!(spv_parsed_operand_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<spv_parsed_operand_t>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(spv_parsed_operand_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<spv_parsed_operand_t>())).offset as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_parsed_operand_t),
+ "::",
+ stringify!(offset)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<spv_parsed_operand_t>())).num_words as *const _ as usize },
+ 2usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_parsed_operand_t),
+ "::",
+ stringify!(num_words)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<spv_parsed_operand_t>())).type_ as *const _ as usize },
+ 4usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_parsed_operand_t),
+ "::",
+ stringify!(type_)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<spv_parsed_operand_t>())).number_kind as *const _ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_parsed_operand_t),
+ "::",
+ stringify!(number_kind)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<spv_parsed_operand_t>())).number_bit_width as *const _ as usize
+ },
+ 12usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_parsed_operand_t),
+ "::",
+ stringify!(number_bit_width)
+ )
+ );
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct spv_parsed_instruction_t {
+ pub words: *const u32,
+ pub num_words: u16,
+ pub opcode: u16,
+ pub ext_inst_type: spv_ext_inst_type_t,
+ pub type_id: u32,
+ pub result_id: u32,
+ pub operands: *const spv_parsed_operand_t,
+ pub num_operands: u16,
+}
+#[test]
+fn bindgen_test_layout_spv_parsed_instruction_t() {
+ assert_eq!(
+ ::std::mem::size_of::<spv_parsed_instruction_t>(),
+ 40usize,
+ concat!("Size of: ", stringify!(spv_parsed_instruction_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<spv_parsed_instruction_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(spv_parsed_instruction_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<spv_parsed_instruction_t>())).words as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_parsed_instruction_t),
+ "::",
+ stringify!(words)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<spv_parsed_instruction_t>())).num_words as *const _ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_parsed_instruction_t),
+ "::",
+ stringify!(num_words)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<spv_parsed_instruction_t>())).opcode as *const _ as usize },
+ 10usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_parsed_instruction_t),
+ "::",
+ stringify!(opcode)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<spv_parsed_instruction_t>())).ext_inst_type as *const _ as usize
+ },
+ 12usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_parsed_instruction_t),
+ "::",
+ stringify!(ext_inst_type)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<spv_parsed_instruction_t>())).type_id as *const _ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_parsed_instruction_t),
+ "::",
+ stringify!(type_id)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<spv_parsed_instruction_t>())).result_id as *const _ as usize
+ },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_parsed_instruction_t),
+ "::",
+ stringify!(result_id)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<spv_parsed_instruction_t>())).operands as *const _ as usize
+ },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_parsed_instruction_t),
+ "::",
+ stringify!(operands)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<spv_parsed_instruction_t>())).num_operands as *const _ as usize
+ },
+ 32usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_parsed_instruction_t),
+ "::",
+ stringify!(num_operands)
+ )
+ );
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct spv_const_binary_t {
+ pub code: *const u32,
+ pub wordCount: usize,
+}
+#[test]
+fn bindgen_test_layout_spv_const_binary_t() {
+ assert_eq!(
+ ::std::mem::size_of::<spv_const_binary_t>(),
+ 16usize,
+ concat!("Size of: ", stringify!(spv_const_binary_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<spv_const_binary_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(spv_const_binary_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<spv_const_binary_t>())).code as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_const_binary_t),
+ "::",
+ stringify!(code)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<spv_const_binary_t>())).wordCount as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_const_binary_t),
+ "::",
+ stringify!(wordCount)
+ )
+ );
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct spv_binary_t {
+ pub code: *mut u32,
+ pub wordCount: usize,
+}
+#[test]
+fn bindgen_test_layout_spv_binary_t() {
+ assert_eq!(
+ ::std::mem::size_of::<spv_binary_t>(),
+ 16usize,
+ concat!("Size of: ", stringify!(spv_binary_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<spv_binary_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(spv_binary_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<spv_binary_t>())).code as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_binary_t),
+ "::",
+ stringify!(code)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<spv_binary_t>())).wordCount as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_binary_t),
+ "::",
+ stringify!(wordCount)
+ )
+ );
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct spv_text_t {
+ pub str_: *const ::std::os::raw::c_char,
+ pub length: usize,
+}
+#[test]
+fn bindgen_test_layout_spv_text_t() {
+ assert_eq!(
+ ::std::mem::size_of::<spv_text_t>(),
+ 16usize,
+ concat!("Size of: ", stringify!(spv_text_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<spv_text_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(spv_text_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<spv_text_t>())).str_ as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_text_t),
+ "::",
+ stringify!(str_)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<spv_text_t>())).length as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_text_t),
+ "::",
+ stringify!(length)
+ )
+ );
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct spv_position_t {
+ pub line: usize,
+ pub column: usize,
+ pub index: usize,
+}
+#[test]
+fn bindgen_test_layout_spv_position_t() {
+ assert_eq!(
+ ::std::mem::size_of::<spv_position_t>(),
+ 24usize,
+ concat!("Size of: ", stringify!(spv_position_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<spv_position_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(spv_position_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<spv_position_t>())).line as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_position_t),
+ "::",
+ stringify!(line)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<spv_position_t>())).column as *const _ as usize },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_position_t),
+ "::",
+ stringify!(column)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<spv_position_t>())).index as *const _ as usize },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_position_t),
+ "::",
+ stringify!(index)
+ )
+ );
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct spv_diagnostic_t {
+ pub position: spv_position_t,
+ pub error: *mut ::std::os::raw::c_char,
+ pub isTextSource: bool,
+}
+#[test]
+fn bindgen_test_layout_spv_diagnostic_t() {
+ assert_eq!(
+ ::std::mem::size_of::<spv_diagnostic_t>(),
+ 40usize,
+ concat!("Size of: ", stringify!(spv_diagnostic_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<spv_diagnostic_t>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(spv_diagnostic_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<spv_diagnostic_t>())).position as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_diagnostic_t),
+ "::",
+ stringify!(position)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<spv_diagnostic_t>())).error as *const _ as usize },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_diagnostic_t),
+ "::",
+ stringify!(error)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<spv_diagnostic_t>())).isTextSource as *const _ as usize },
+ 32usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(spv_diagnostic_t),
+ "::",
+ stringify!(isTextSource)
+ )
+ );
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct spv_context_t {
+ _unused: [u8; 0],
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct spv_validator_options_t {
+ _unused: [u8; 0],
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct spv_optimizer_options_t {
+ _unused: [u8; 0],
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct spv_reducer_options_t {
+ _unused: [u8; 0],
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct spv_fuzzer_options_t {
+ _unused: [u8; 0],
+}
+pub type spv_const_binary = *mut spv_const_binary_t;
+pub type spv_binary = *mut spv_binary_t;
+pub type spv_text = *mut spv_text_t;
+pub type spv_position = *mut spv_position_t;
+pub type spv_diagnostic = *mut spv_diagnostic_t;
+pub type spv_const_context = *const spv_context_t;
+pub type spv_context = *mut spv_context_t;
+pub type spv_validator_options = *mut spv_validator_options_t;
+pub type spv_const_validator_options = *const spv_validator_options_t;
+pub type spv_optimizer_options = *mut spv_optimizer_options_t;
+pub type spv_const_optimizer_options = *const spv_optimizer_options_t;
+pub type spv_reducer_options = *mut spv_reducer_options_t;
+pub type spv_const_reducer_options = *const spv_reducer_options_t;
+pub type spv_fuzzer_options = *mut spv_fuzzer_options_t;
+pub type spv_const_fuzzer_options = *const spv_fuzzer_options_t;
+extern "C" {
+ pub fn spvSoftwareVersionString() -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn spvSoftwareVersionDetailsString() -> *const ::std::os::raw::c_char;
+}
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum spv_target_env {
+ SPV_ENV_UNIVERSAL_1_0 = 0,
+ SPV_ENV_VULKAN_1_0 = 1,
+ SPV_ENV_UNIVERSAL_1_1 = 2,
+ SPV_ENV_OPENCL_2_1 = 3,
+ SPV_ENV_OPENCL_2_2 = 4,
+ SPV_ENV_OPENGL_4_0 = 5,
+ SPV_ENV_OPENGL_4_1 = 6,
+ SPV_ENV_OPENGL_4_2 = 7,
+ SPV_ENV_OPENGL_4_3 = 8,
+ SPV_ENV_OPENGL_4_5 = 9,
+ SPV_ENV_UNIVERSAL_1_2 = 10,
+ SPV_ENV_OPENCL_1_2 = 11,
+ SPV_ENV_OPENCL_EMBEDDED_1_2 = 12,
+ SPV_ENV_OPENCL_2_0 = 13,
+ SPV_ENV_OPENCL_EMBEDDED_2_0 = 14,
+ SPV_ENV_OPENCL_EMBEDDED_2_1 = 15,
+ SPV_ENV_OPENCL_EMBEDDED_2_2 = 16,
+ SPV_ENV_UNIVERSAL_1_3 = 17,
+ SPV_ENV_VULKAN_1_1 = 18,
+ SPV_ENV_WEBGPU_0 = 19,
+ SPV_ENV_UNIVERSAL_1_4 = 20,
+ SPV_ENV_VULKAN_1_1_SPIRV_1_4 = 21,
+ SPV_ENV_UNIVERSAL_1_5 = 22,
+ SPV_ENV_VULKAN_1_2 = 23,
+}
+#[repr(u32)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub enum spv_validator_limit {
+ spv_validator_limit_max_struct_members = 0,
+ spv_validator_limit_max_struct_depth = 1,
+ spv_validator_limit_max_local_variables = 2,
+ spv_validator_limit_max_global_variables = 3,
+ spv_validator_limit_max_switch_branches = 4,
+ spv_validator_limit_max_function_args = 5,
+ spv_validator_limit_max_control_flow_nesting_depth = 6,
+ spv_validator_limit_max_access_chain_indexes = 7,
+ spv_validator_limit_max_id_bound = 8,
+}
+extern "C" {
+ pub fn spvTargetEnvDescription(env: spv_target_env) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn spvParseTargetEnv(s: *const ::std::os::raw::c_char, env: *mut spv_target_env) -> bool;
+}
+extern "C" {
+ pub fn spvParseVulkanEnv(vulkan_ver: u32, spirv_ver: u32, env: *mut spv_target_env) -> bool;
+}
+extern "C" {
+ pub fn spvContextCreate(env: spv_target_env) -> spv_context;
+}
+extern "C" {
+ pub fn spvContextDestroy(context: spv_context);
+}
+extern "C" {
+ pub fn spvValidatorOptionsCreate() -> spv_validator_options;
+}
+extern "C" {
+ pub fn spvValidatorOptionsDestroy(options: spv_validator_options);
+}
+extern "C" {
+ pub fn spvValidatorOptionsSetUniversalLimit(
+ options: spv_validator_options,
+ limit_type: spv_validator_limit,
+ limit: u32,
+ );
+}
+extern "C" {
+ pub fn spvValidatorOptionsSetRelaxStoreStruct(options: spv_validator_options, val: bool);
+}
+extern "C" {
+ pub fn spvValidatorOptionsSetRelaxLogicalPointer(options: spv_validator_options, val: bool);
+}
+extern "C" {
+ pub fn spvValidatorOptionsSetBeforeHlslLegalization(options: spv_validator_options, val: bool);
+}
+extern "C" {
+ pub fn spvValidatorOptionsSetRelaxBlockLayout(options: spv_validator_options, val: bool);
+}
+extern "C" {
+ pub fn spvValidatorOptionsSetUniformBufferStandardLayout(
+ options: spv_validator_options,
+ val: bool,
+ );
+}
+extern "C" {
+ pub fn spvValidatorOptionsSetScalarBlockLayout(options: spv_validator_options, val: bool);
+}
+extern "C" {
+ pub fn spvValidatorOptionsSetSkipBlockLayout(options: spv_validator_options, val: bool);
+}
+extern "C" {
+ pub fn spvOptimizerOptionsCreate() -> spv_optimizer_options;
+}
+extern "C" {
+ pub fn spvOptimizerOptionsDestroy(options: spv_optimizer_options);
+}
+extern "C" {
+ pub fn spvOptimizerOptionsSetRunValidator(options: spv_optimizer_options, val: bool);
+}
+extern "C" {
+ pub fn spvOptimizerOptionsSetValidatorOptions(
+ options: spv_optimizer_options,
+ val: spv_validator_options,
+ );
+}
+extern "C" {
+ pub fn spvOptimizerOptionsSetMaxIdBound(options: spv_optimizer_options, val: u32);
+}
+extern "C" {
+ pub fn spvOptimizerOptionsSetPreserveBindings(options: spv_optimizer_options, val: bool);
+}
+extern "C" {
+ pub fn spvOptimizerOptionsSetPreserveSpecConstants(options: spv_optimizer_options, val: bool);
+}
+extern "C" {
+ pub fn spvReducerOptionsCreate() -> spv_reducer_options;
+}
+extern "C" {
+ pub fn spvReducerOptionsDestroy(options: spv_reducer_options);
+}
+extern "C" {
+ pub fn spvReducerOptionsSetStepLimit(options: spv_reducer_options, step_limit: u32);
+}
+extern "C" {
+ pub fn spvReducerOptionsSetFailOnValidationError(
+ options: spv_reducer_options,
+ fail_on_validation_error: bool,
+ );
+}
+extern "C" {
+ pub fn spvFuzzerOptionsCreate() -> spv_fuzzer_options;
+}
+extern "C" {
+ pub fn spvFuzzerOptionsDestroy(options: spv_fuzzer_options);
+}
+extern "C" {
+ pub fn spvFuzzerOptionsEnableReplayValidation(options: spv_fuzzer_options);
+}
+extern "C" {
+ pub fn spvFuzzerOptionsSetRandomSeed(options: spv_fuzzer_options, seed: u32);
+}
+extern "C" {
+ pub fn spvFuzzerOptionsSetShrinkerStepLimit(
+ options: spv_fuzzer_options,
+ shrinker_step_limit: u32,
+ );
+}
+extern "C" {
+ pub fn spvFuzzerOptionsEnableFuzzerPassValidation(options: spv_fuzzer_options);
+}
+extern "C" {
+ pub fn spvTextToBinary(
+ context: spv_const_context,
+ text: *const ::std::os::raw::c_char,
+ length: usize,
+ binary: *mut spv_binary,
+ diagnostic: *mut spv_diagnostic,
+ ) -> spv_result_t;
+}
+extern "C" {
+ pub fn spvTextToBinaryWithOptions(
+ context: spv_const_context,
+ text: *const ::std::os::raw::c_char,
+ length: usize,
+ options: u32,
+ binary: *mut spv_binary,
+ diagnostic: *mut spv_diagnostic,
+ ) -> spv_result_t;
+}
+extern "C" {
+ pub fn spvTextDestroy(text: spv_text);
+}
+extern "C" {
+ pub fn spvBinaryToText(
+ context: spv_const_context,
+ binary: *const u32,
+ word_count: usize,
+ options: u32,
+ text: *mut spv_text,
+ diagnostic: *mut spv_diagnostic,
+ ) -> spv_result_t;
+}
+extern "C" {
+ pub fn spvBinaryDestroy(binary: spv_binary);
+}
+extern "C" {
+ pub fn spvValidate(
+ context: spv_const_context,
+ binary: spv_const_binary,
+ diagnostic: *mut spv_diagnostic,
+ ) -> spv_result_t;
+}
+extern "C" {
+ pub fn spvValidateWithOptions(
+ context: spv_const_context,
+ options: spv_const_validator_options,
+ binary: spv_const_binary,
+ diagnostic: *mut spv_diagnostic,
+ ) -> spv_result_t;
+}
+extern "C" {
+ pub fn spvValidateBinary(
+ context: spv_const_context,
+ words: *const u32,
+ num_words: usize,
+ diagnostic: *mut spv_diagnostic,
+ ) -> spv_result_t;
+}
+extern "C" {
+ pub fn spvDiagnosticCreate(
+ position: spv_position,
+ message: *const ::std::os::raw::c_char,
+ ) -> spv_diagnostic;
+}
+extern "C" {
+ pub fn spvDiagnosticDestroy(diagnostic: spv_diagnostic);
+}
+extern "C" {
+ pub fn spvDiagnosticPrint(diagnostic: spv_diagnostic) -> spv_result_t;
+}
+extern "C" {
+ pub fn spvOpcodeString(opcode: u32) -> *const ::std::os::raw::c_char;
+}
+pub type spv_parsed_header_fn_t = ::std::option::Option<
+ unsafe extern "C" fn(
+ user_data: *mut ::std::os::raw::c_void,
+ endian: spv_endianness_t,
+ magic: u32,
+ version: u32,
+ generator: u32,
+ id_bound: u32,
+ reserved: u32,
+ ) -> spv_result_t,
+>;
+pub type spv_parsed_instruction_fn_t = ::std::option::Option<
+ unsafe extern "C" fn(
+ user_data: *mut ::std::os::raw::c_void,
+ parsed_instruction: *const spv_parsed_instruction_t,
+ ) -> spv_result_t,
+>;
+extern "C" {
+ pub fn spvBinaryParse(
+ context: spv_const_context,
+ user_data: *mut ::std::os::raw::c_void,
+ words: *const u32,
+ num_words: usize,
+ parse_header: spv_parsed_header_fn_t,
+ parse_instruction: spv_parsed_instruction_fn_t,
+ diagnostic: *mut spv_diagnostic,
+ ) -> spv_result_t;
+}
diff --git a/zluda/Cargo.toml b/zluda/Cargo.toml
new file mode 100644
index 0000000..218fe8f
--- /dev/null
+++ b/zluda/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+name = "zluda"
+version = "0.0.0"
+authors = ["Andrzej Janik <[email protected]>"]
+edition = "2018"
+
+[lib]
+name = "zluda"
+crate-type = ["cdylib"]
+
+[dependencies]
+ptx = { path = "../ptx" }
+level_zero = { path = "../level_zero" }
+level_zero-sys = { path = "../level_zero-sys" }
+lazy_static = "1.4"
+num_enum = "0.4"
+lz4 = "1.23"
+
+[dev-dependencies]
+cuda-driver-sys = "0.3.0"
+paste = "1.0" \ No newline at end of file
diff --git a/zluda/README b/zluda/README
new file mode 100644
index 0000000..089ddcd
--- /dev/null
+++ b/zluda/README
@@ -0,0 +1,3 @@
+bindgen /usr/local/cuda/include/cuda.h -o cuda.rs --whitelist-function="^cu.*" --size_t-is-usize --default-enum-style=newtype --no-layout-tests --no-doc-comments --no-derive-debug --new-type-alias "^CUdevice$|^CUdeviceptr$"
+sed -i -e 's/extern "C" {//g' -e 's/-> CUresult;/-> CUresult { impl_::unsupported()/g' -e 's/pub fn /#[no_mangle] pub extern "C" fn /g' cuda.rs
+rustfmt cuda.rs \ No newline at end of file
diff --git a/zluda/build.rs b/zluda/build.rs
new file mode 100644
index 0000000..3b8999f
--- /dev/null
+++ b/zluda/build.rs
@@ -0,0 +1,27 @@
+// HACK ALERT
+// This buidl script has been copy-pasted from cl-sys to avoid CUDA libraries
+// overriding path to OpenCL
+
+ fn main() {
+ if cfg!(windows) {
+ let known_sdk = [
+ // E.g. "c:\Program Files (x86)\Intel\OpenCL SDK\lib\x86\"
+ ("INTELOCLSDKROOT", "x64", "x86"),
+ // E.g. "c:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\lib\Win32\"
+ ("CUDA_PATH", "x64", "Win32"),
+ // E.g. "C:\Program Files (x86)\AMD APP SDK\3.0\lib\x86\"
+ ("AMDAPPSDKROOT", "x86_64", "x86"),
+ ];
+
+ for info in known_sdk.iter() {
+ if let Ok(sdk) = std::env::var(info.0) {
+ let mut path = std::path::PathBuf::from(sdk);
+ path.push("lib");
+ path.push(if cfg!(target_arch="x86_64") { info.1 } else { info.2 });
+ println!("cargo:rustc-link-search=native={}", path.display());
+ }
+ }
+
+ println!("cargo:rustc-link-search=native=C:\\Program Files (x86)\\OCL_SDK_Light\\lib\\x86_64");
+ }
+} \ No newline at end of file
diff --git a/zluda/src/cuda.rs b/zluda/src/cuda.rs
new file mode 100644
index 0000000..2dc26f5
--- /dev/null
+++ b/zluda/src/cuda.rs
@@ -0,0 +1,4496 @@
+use super::r#impl;
+use super::r#impl::{Decuda, Encuda};
+
+/* automatically generated by rust-bindgen 0.55.1 */
+
+pub type __uint32_t = ::std::os::raw::c_uint;
+pub type __uint64_t = ::std::os::raw::c_ulong;
+pub type cuuint32_t = u32;
+pub type cuuint64_t = u64;
+#[repr(transparent)]
+#[derive(Copy, Clone)]
+pub struct CUdeviceptr(pub ::std::os::raw::c_ulonglong);
+#[repr(transparent)]
+#[derive(Copy, Clone)]
+pub struct CUdevice(pub ::std::os::raw::c_int);
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUctx_st {
+ _unused: [u8; 0],
+}
+pub type CUcontext = *mut CUctx_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUmod_st {
+ _unused: [u8; 0],
+}
+pub type CUmodule = *mut CUmod_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUfunc_st {
+ _unused: [u8; 0],
+}
+pub type CUfunction = *mut CUfunc_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUarray_st {
+ _unused: [u8; 0],
+}
+pub type CUarray = *mut CUarray_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUmipmappedArray_st {
+ _unused: [u8; 0],
+}
+pub type CUmipmappedArray = *mut CUmipmappedArray_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUtexref_st {
+ _unused: [u8; 0],
+}
+pub type CUtexref = *mut CUtexref_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUsurfref_st {
+ _unused: [u8; 0],
+}
+pub type CUsurfref = *mut CUsurfref_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUevent_st {
+ _unused: [u8; 0],
+}
+pub type CUevent = *mut CUevent_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUstream_st {
+ _unused: [u8; 0],
+}
+pub type CUstream = *mut CUstream_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUgraphicsResource_st {
+ _unused: [u8; 0],
+}
+pub type CUgraphicsResource = *mut CUgraphicsResource_st;
+pub type CUtexObject = ::std::os::raw::c_ulonglong;
+pub type CUsurfObject = ::std::os::raw::c_ulonglong;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUextMemory_st {
+ _unused: [u8; 0],
+}
+pub type CUexternalMemory = *mut CUextMemory_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUextSemaphore_st {
+ _unused: [u8; 0],
+}
+pub type CUexternalSemaphore = *mut CUextSemaphore_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUgraph_st {
+ _unused: [u8; 0],
+}
+pub type CUgraph = *mut CUgraph_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUgraphNode_st {
+ _unused: [u8; 0],
+}
+pub type CUgraphNode = *mut CUgraphNode_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUgraphExec_st {
+ _unused: [u8; 0],
+}
+pub type CUgraphExec = *mut CUgraphExec_st;
+#[repr(C)]
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub struct CUuuid_st {
+ pub bytes: [::std::os::raw::c_uchar; 16usize],
+}
+pub type CUuuid = CUuuid_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUipcEventHandle_st {
+ pub reserved: [::std::os::raw::c_char; 64usize],
+}
+pub type CUipcEventHandle = CUipcEventHandle_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUipcMemHandle_st {
+ pub reserved: [::std::os::raw::c_char; 64usize],
+}
+pub type CUipcMemHandle = CUipcMemHandle_st;
+impl CUstreamBatchMemOpType_enum {
+ pub const CU_STREAM_MEM_OP_WAIT_VALUE_32: CUstreamBatchMemOpType_enum =
+ CUstreamBatchMemOpType_enum(1);
+}
+impl CUstreamBatchMemOpType_enum {
+ pub const CU_STREAM_MEM_OP_WRITE_VALUE_32: CUstreamBatchMemOpType_enum =
+ CUstreamBatchMemOpType_enum(2);
+}
+impl CUstreamBatchMemOpType_enum {
+ pub const CU_STREAM_MEM_OP_WAIT_VALUE_64: CUstreamBatchMemOpType_enum =
+ CUstreamBatchMemOpType_enum(4);
+}
+impl CUstreamBatchMemOpType_enum {
+ pub const CU_STREAM_MEM_OP_WRITE_VALUE_64: CUstreamBatchMemOpType_enum =
+ CUstreamBatchMemOpType_enum(5);
+}
+impl CUstreamBatchMemOpType_enum {
+ pub const CU_STREAM_MEM_OP_FLUSH_REMOTE_WRITES: CUstreamBatchMemOpType_enum =
+ CUstreamBatchMemOpType_enum(3);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUstreamBatchMemOpType_enum(pub ::std::os::raw::c_uint);
+pub use self::CUstreamBatchMemOpType_enum as CUstreamBatchMemOpType;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union CUstreamBatchMemOpParams_union {
+ pub operation: CUstreamBatchMemOpType,
+ pub waitValue: CUstreamBatchMemOpParams_union_CUstreamMemOpWaitValueParams_st,
+ pub writeValue: CUstreamBatchMemOpParams_union_CUstreamMemOpWriteValueParams_st,
+ pub flushRemoteWrites: CUstreamBatchMemOpParams_union_CUstreamMemOpFlushRemoteWritesParams_st,
+ pub pad: [cuuint64_t; 6usize],
+ _bindgen_union_align: [u64; 6usize],
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUstreamBatchMemOpParams_union_CUstreamMemOpWaitValueParams_st {
+ pub operation: CUstreamBatchMemOpType,
+ pub address: CUdeviceptr,
+ pub __bindgen_anon_1:
+ CUstreamBatchMemOpParams_union_CUstreamMemOpWaitValueParams_st__bindgen_ty_1,
+ pub flags: ::std::os::raw::c_uint,
+ pub alias: CUdeviceptr,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union CUstreamBatchMemOpParams_union_CUstreamMemOpWaitValueParams_st__bindgen_ty_1 {
+ pub value: cuuint32_t,
+ pub value64: cuuint64_t,
+ _bindgen_union_align: u64,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUstreamBatchMemOpParams_union_CUstreamMemOpWriteValueParams_st {
+ pub operation: CUstreamBatchMemOpType,
+ pub address: CUdeviceptr,
+ pub __bindgen_anon_1:
+ CUstreamBatchMemOpParams_union_CUstreamMemOpWriteValueParams_st__bindgen_ty_1,
+ pub flags: ::std::os::raw::c_uint,
+ pub alias: CUdeviceptr,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union CUstreamBatchMemOpParams_union_CUstreamMemOpWriteValueParams_st__bindgen_ty_1 {
+ pub value: cuuint32_t,
+ pub value64: cuuint64_t,
+ _bindgen_union_align: u64,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUstreamBatchMemOpParams_union_CUstreamMemOpFlushRemoteWritesParams_st {
+ pub operation: CUstreamBatchMemOpType,
+ pub flags: ::std::os::raw::c_uint,
+}
+pub type CUstreamBatchMemOpParams = CUstreamBatchMemOpParams_union;
+impl CUarray_format_enum {
+ pub const CU_AD_FORMAT_UNSIGNED_INT8: CUarray_format_enum = CUarray_format_enum(1);
+}
+impl CUarray_format_enum {
+ pub const CU_AD_FORMAT_UNSIGNED_INT16: CUarray_format_enum = CUarray_format_enum(2);
+}
+impl CUarray_format_enum {
+ pub const CU_AD_FORMAT_UNSIGNED_INT32: CUarray_format_enum = CUarray_format_enum(3);
+}
+impl CUarray_format_enum {
+ pub const CU_AD_FORMAT_SIGNED_INT8: CUarray_format_enum = CUarray_format_enum(8);
+}
+impl CUarray_format_enum {
+ pub const CU_AD_FORMAT_SIGNED_INT16: CUarray_format_enum = CUarray_format_enum(9);
+}
+impl CUarray_format_enum {
+ pub const CU_AD_FORMAT_SIGNED_INT32: CUarray_format_enum = CUarray_format_enum(10);
+}
+impl CUarray_format_enum {
+ pub const CU_AD_FORMAT_HALF: CUarray_format_enum = CUarray_format_enum(16);
+}
+impl CUarray_format_enum {
+ pub const CU_AD_FORMAT_FLOAT: CUarray_format_enum = CUarray_format_enum(32);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUarray_format_enum(pub ::std::os::raw::c_uint);
+pub use self::CUarray_format_enum as CUarray_format;
+impl CUaddress_mode_enum {
+ pub const CU_TR_ADDRESS_MODE_WRAP: CUaddress_mode_enum = CUaddress_mode_enum(0);
+}
+impl CUaddress_mode_enum {
+ pub const CU_TR_ADDRESS_MODE_CLAMP: CUaddress_mode_enum = CUaddress_mode_enum(1);
+}
+impl CUaddress_mode_enum {
+ pub const CU_TR_ADDRESS_MODE_MIRROR: CUaddress_mode_enum = CUaddress_mode_enum(2);
+}
+impl CUaddress_mode_enum {
+ pub const CU_TR_ADDRESS_MODE_BORDER: CUaddress_mode_enum = CUaddress_mode_enum(3);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUaddress_mode_enum(pub ::std::os::raw::c_uint);
+pub use self::CUaddress_mode_enum as CUaddress_mode;
+impl CUfilter_mode_enum {
+ pub const CU_TR_FILTER_MODE_POINT: CUfilter_mode_enum = CUfilter_mode_enum(0);
+}
+impl CUfilter_mode_enum {
+ pub const CU_TR_FILTER_MODE_LINEAR: CUfilter_mode_enum = CUfilter_mode_enum(1);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUfilter_mode_enum(pub ::std::os::raw::c_uint);
+pub use self::CUfilter_mode_enum as CUfilter_mode;
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(1);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_X: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(2);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Y: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(3);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Z: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(4);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_X: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(5);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Y: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(6);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Z: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(7);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAX_SHARED_MEMORY_PER_BLOCK: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(8);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_SHARED_MEMORY_PER_BLOCK: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(8);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_TOTAL_CONSTANT_MEMORY: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(9);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_WARP_SIZE: CUdevice_attribute_enum = CUdevice_attribute_enum(10);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAX_PITCH: CUdevice_attribute_enum = CUdevice_attribute_enum(11);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_BLOCK: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(12);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_REGISTERS_PER_BLOCK: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(12);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_CLOCK_RATE: CUdevice_attribute_enum = CUdevice_attribute_enum(13);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(14);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_GPU_OVERLAP: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(15);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(16);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(17);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_INTEGRATED: CUdevice_attribute_enum = CUdevice_attribute_enum(18);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(19);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_COMPUTE_MODE: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(20);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(21);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(22);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_HEIGHT: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(23);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(24);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_HEIGHT: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(25);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_DEPTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(26);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_LAYERED_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(27);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_LAYERED_HEIGHT: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(28);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_LAYERED_LAYERS: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(29);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(27);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_HEIGHT: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(28);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_NUMSLICES: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(29);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_SURFACE_ALIGNMENT: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(30);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_CONCURRENT_KERNELS: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(31);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_ECC_ENABLED: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(32);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_PCI_BUS_ID: CUdevice_attribute_enum = CUdevice_attribute_enum(33);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(34);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_TCC_DRIVER: CUdevice_attribute_enum = CUdevice_attribute_enum(35);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MEMORY_CLOCK_RATE: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(36);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_GLOBAL_MEMORY_BUS_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(37);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_L2_CACHE_SIZE: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(38);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_MULTIPROCESSOR: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(39);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_ASYNC_ENGINE_COUNT: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(40);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_UNIFIED_ADDRESSING: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(41);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_LAYERED_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(42);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_LAYERED_LAYERS: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(43);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_CAN_TEX2D_GATHER: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(44);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_GATHER_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(45);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_GATHER_HEIGHT: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(46);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_WIDTH_ALTERNATE: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(47);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_HEIGHT_ALTERNATE: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(48);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_DEPTH_ALTERNATE: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(49);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(50);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_TEXTURE_PITCH_ALIGNMENT: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(51);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURECUBEMAP_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(52);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURECUBEMAP_LAYERED_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(53);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURECUBEMAP_LAYERED_LAYERS: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(54);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE1D_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(55);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE2D_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(56);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE2D_HEIGHT: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(57);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE3D_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(58);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE3D_HEIGHT: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(59);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE3D_DEPTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(60);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE1D_LAYERED_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(61);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE1D_LAYERED_LAYERS: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(62);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE2D_LAYERED_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(63);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE2D_LAYERED_HEIGHT: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(64);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACE2D_LAYERED_LAYERS: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(65);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACECUBEMAP_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(66);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACECUBEMAP_LAYERED_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(67);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_SURFACECUBEMAP_LAYERED_LAYERS: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(68);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_LINEAR_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(69);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_LINEAR_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(70);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_LINEAR_HEIGHT: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(71);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_LINEAR_PITCH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(72);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_MIPMAPPED_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(73);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_MIPMAPPED_HEIGHT: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(74);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(75);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(76);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_MIPMAPPED_WIDTH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(77);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_STREAM_PRIORITIES_SUPPORTED: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(78);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_GLOBAL_L1_CACHE_SUPPORTED: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(79);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_LOCAL_L1_CACHE_SUPPORTED: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(80);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAX_SHARED_MEMORY_PER_MULTIPROCESSOR: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(81);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_MULTIPROCESSOR: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(82);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MANAGED_MEMORY: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(83);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MULTI_GPU_BOARD: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(84);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MULTI_GPU_BOARD_GROUP_ID: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(85);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_HOST_NATIVE_ATOMIC_SUPPORTED: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(86);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_SINGLE_TO_DOUBLE_PRECISION_PERF_RATIO: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(87);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_PAGEABLE_MEMORY_ACCESS: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(88);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_CONCURRENT_MANAGED_ACCESS: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(89);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_COMPUTE_PREEMPTION_SUPPORTED: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(90);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_CAN_USE_HOST_POINTER_FOR_REGISTERED_MEM: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(91);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_CAN_USE_STREAM_MEM_OPS: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(92);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_CAN_USE_64_BIT_STREAM_MEM_OPS: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(93);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_CAN_USE_STREAM_WAIT_VALUE_NOR: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(94);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_COOPERATIVE_LAUNCH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(95);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_COOPERATIVE_MULTI_DEVICE_LAUNCH: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(96);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAX_SHARED_MEMORY_PER_BLOCK_OPTIN: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(97);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_CAN_FLUSH_REMOTE_WRITES: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(98);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_HOST_REGISTER_SUPPORTED: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(99);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_PAGEABLE_MEMORY_ACCESS_USES_HOST_PAGE_TABLES:
+ CUdevice_attribute_enum = CUdevice_attribute_enum(100);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_DIRECT_MANAGED_MEM_ACCESS_FROM_HOST: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(101);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_VIRTUAL_ADDRESS_MANAGEMENT_SUPPORTED: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(102);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR_SUPPORTED:
+ CUdevice_attribute_enum = CUdevice_attribute_enum(103);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_HANDLE_TYPE_WIN32_HANDLE_SUPPORTED: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(104);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_HANDLE_TYPE_WIN32_KMT_HANDLE_SUPPORTED: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(105);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAX_BLOCKS_PER_MULTIPROCESSOR: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(106);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_GENERIC_COMPRESSION_SUPPORTED: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(107);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAX_PERSISTING_L2_CACHE_SIZE: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(108);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAX_ACCESS_POLICY_WINDOW_SIZE: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(109);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_GPU_DIRECT_RDMA_WITH_CUDA_VMM_SUPPORTED: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(110);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_RESERVED_SHARED_MEMORY_PER_BLOCK: CUdevice_attribute_enum =
+ CUdevice_attribute_enum(111);
+}
+impl CUdevice_attribute_enum {
+ pub const CU_DEVICE_ATTRIBUTE_MAX: CUdevice_attribute_enum = CUdevice_attribute_enum(112);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUdevice_attribute_enum(pub ::std::os::raw::c_uint);
+pub use self::CUdevice_attribute_enum as CUdevice_attribute;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUdevprop_st {
+ pub maxThreadsPerBlock: ::std::os::raw::c_int,
+ pub maxThreadsDim: [::std::os::raw::c_int; 3usize],
+ pub maxGridSize: [::std::os::raw::c_int; 3usize],
+ pub sharedMemPerBlock: ::std::os::raw::c_int,
+ pub totalConstantMemory: ::std::os::raw::c_int,
+ pub SIMDWidth: ::std::os::raw::c_int,
+ pub memPitch: ::std::os::raw::c_int,
+ pub regsPerBlock: ::std::os::raw::c_int,
+ pub clockRate: ::std::os::raw::c_int,
+ pub textureAlign: ::std::os::raw::c_int,
+}
+pub type CUdevprop = CUdevprop_st;
+impl CUpointer_attribute_enum {
+ pub const CU_POINTER_ATTRIBUTE_CONTEXT: CUpointer_attribute_enum = CUpointer_attribute_enum(1);
+}
+impl CUpointer_attribute_enum {
+ pub const CU_POINTER_ATTRIBUTE_MEMORY_TYPE: CUpointer_attribute_enum =
+ CUpointer_attribute_enum(2);
+}
+impl CUpointer_attribute_enum {
+ pub const CU_POINTER_ATTRIBUTE_DEVICE_POINTER: CUpointer_attribute_enum =
+ CUpointer_attribute_enum(3);
+}
+impl CUpointer_attribute_enum {
+ pub const CU_POINTER_ATTRIBUTE_HOST_POINTER: CUpointer_attribute_enum =
+ CUpointer_attribute_enum(4);
+}
+impl CUpointer_attribute_enum {
+ pub const CU_POINTER_ATTRIBUTE_P2P_TOKENS: CUpointer_attribute_enum =
+ CUpointer_attribute_enum(5);
+}
+impl CUpointer_attribute_enum {
+ pub const CU_POINTER_ATTRIBUTE_SYNC_MEMOPS: CUpointer_attribute_enum =
+ CUpointer_attribute_enum(6);
+}
+impl CUpointer_attribute_enum {
+ pub const CU_POINTER_ATTRIBUTE_BUFFER_ID: CUpointer_attribute_enum =
+ CUpointer_attribute_enum(7);
+}
+impl CUpointer_attribute_enum {
+ pub const CU_POINTER_ATTRIBUTE_IS_MANAGED: CUpointer_attribute_enum =
+ CUpointer_attribute_enum(8);
+}
+impl CUpointer_attribute_enum {
+ pub const CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL: CUpointer_attribute_enum =
+ CUpointer_attribute_enum(9);
+}
+impl CUpointer_attribute_enum {
+ pub const CU_POINTER_ATTRIBUTE_IS_LEGACY_CUDA_IPC_CAPABLE: CUpointer_attribute_enum =
+ CUpointer_attribute_enum(10);
+}
+impl CUpointer_attribute_enum {
+ pub const CU_POINTER_ATTRIBUTE_RANGE_START_ADDR: CUpointer_attribute_enum =
+ CUpointer_attribute_enum(11);
+}
+impl CUpointer_attribute_enum {
+ pub const CU_POINTER_ATTRIBUTE_RANGE_SIZE: CUpointer_attribute_enum =
+ CUpointer_attribute_enum(12);
+}
+impl CUpointer_attribute_enum {
+ pub const CU_POINTER_ATTRIBUTE_MAPPED: CUpointer_attribute_enum = CUpointer_attribute_enum(13);
+}
+impl CUpointer_attribute_enum {
+ pub const CU_POINTER_ATTRIBUTE_ALLOWED_HANDLE_TYPES: CUpointer_attribute_enum =
+ CUpointer_attribute_enum(14);
+}
+impl CUpointer_attribute_enum {
+ pub const CU_POINTER_ATTRIBUTE_IS_GPU_DIRECT_RDMA_CAPABLE: CUpointer_attribute_enum =
+ CUpointer_attribute_enum(15);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUpointer_attribute_enum(pub ::std::os::raw::c_uint);
+pub use self::CUpointer_attribute_enum as CUpointer_attribute;
+impl CUfunction_attribute_enum {
+ pub const CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK: CUfunction_attribute_enum =
+ CUfunction_attribute_enum(0);
+}
+impl CUfunction_attribute_enum {
+ pub const CU_FUNC_ATTRIBUTE_SHARED_SIZE_BYTES: CUfunction_attribute_enum =
+ CUfunction_attribute_enum(1);
+}
+impl CUfunction_attribute_enum {
+ pub const CU_FUNC_ATTRIBUTE_CONST_SIZE_BYTES: CUfunction_attribute_enum =
+ CUfunction_attribute_enum(2);
+}
+impl CUfunction_attribute_enum {
+ pub const CU_FUNC_ATTRIBUTE_LOCAL_SIZE_BYTES: CUfunction_attribute_enum =
+ CUfunction_attribute_enum(3);
+}
+impl CUfunction_attribute_enum {
+ pub const CU_FUNC_ATTRIBUTE_NUM_REGS: CUfunction_attribute_enum = CUfunction_attribute_enum(4);
+}
+impl CUfunction_attribute_enum {
+ pub const CU_FUNC_ATTRIBUTE_PTX_VERSION: CUfunction_attribute_enum =
+ CUfunction_attribute_enum(5);
+}
+impl CUfunction_attribute_enum {
+ pub const CU_FUNC_ATTRIBUTE_BINARY_VERSION: CUfunction_attribute_enum =
+ CUfunction_attribute_enum(6);
+}
+impl CUfunction_attribute_enum {
+ pub const CU_FUNC_ATTRIBUTE_CACHE_MODE_CA: CUfunction_attribute_enum =
+ CUfunction_attribute_enum(7);
+}
+impl CUfunction_attribute_enum {
+ pub const CU_FUNC_ATTRIBUTE_MAX_DYNAMIC_SHARED_SIZE_BYTES: CUfunction_attribute_enum =
+ CUfunction_attribute_enum(8);
+}
+impl CUfunction_attribute_enum {
+ pub const CU_FUNC_ATTRIBUTE_PREFERRED_SHARED_MEMORY_CARVEOUT: CUfunction_attribute_enum =
+ CUfunction_attribute_enum(9);
+}
+impl CUfunction_attribute_enum {
+ pub const CU_FUNC_ATTRIBUTE_MAX: CUfunction_attribute_enum = CUfunction_attribute_enum(10);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUfunction_attribute_enum(pub ::std::os::raw::c_uint);
+pub use self::CUfunction_attribute_enum as CUfunction_attribute;
+impl CUfunc_cache_enum {
+ pub const CU_FUNC_CACHE_PREFER_NONE: CUfunc_cache_enum = CUfunc_cache_enum(0);
+}
+impl CUfunc_cache_enum {
+ pub const CU_FUNC_CACHE_PREFER_SHARED: CUfunc_cache_enum = CUfunc_cache_enum(1);
+}
+impl CUfunc_cache_enum {
+ pub const CU_FUNC_CACHE_PREFER_L1: CUfunc_cache_enum = CUfunc_cache_enum(2);
+}
+impl CUfunc_cache_enum {
+ pub const CU_FUNC_CACHE_PREFER_EQUAL: CUfunc_cache_enum = CUfunc_cache_enum(3);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUfunc_cache_enum(pub ::std::os::raw::c_uint);
+pub use self::CUfunc_cache_enum as CUfunc_cache;
+impl CUsharedconfig_enum {
+ pub const CU_SHARED_MEM_CONFIG_DEFAULT_BANK_SIZE: CUsharedconfig_enum = CUsharedconfig_enum(0);
+}
+impl CUsharedconfig_enum {
+ pub const CU_SHARED_MEM_CONFIG_FOUR_BYTE_BANK_SIZE: CUsharedconfig_enum =
+ CUsharedconfig_enum(1);
+}
+impl CUsharedconfig_enum {
+ pub const CU_SHARED_MEM_CONFIG_EIGHT_BYTE_BANK_SIZE: CUsharedconfig_enum =
+ CUsharedconfig_enum(2);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUsharedconfig_enum(pub ::std::os::raw::c_uint);
+pub use self::CUsharedconfig_enum as CUsharedconfig;
+impl CUmemorytype_enum {
+ pub const CU_MEMORYTYPE_HOST: CUmemorytype_enum = CUmemorytype_enum(1);
+}
+impl CUmemorytype_enum {
+ pub const CU_MEMORYTYPE_DEVICE: CUmemorytype_enum = CUmemorytype_enum(2);
+}
+impl CUmemorytype_enum {
+ pub const CU_MEMORYTYPE_ARRAY: CUmemorytype_enum = CUmemorytype_enum(3);
+}
+impl CUmemorytype_enum {
+ pub const CU_MEMORYTYPE_UNIFIED: CUmemorytype_enum = CUmemorytype_enum(4);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUmemorytype_enum(pub ::std::os::raw::c_uint);
+pub use self::CUmemorytype_enum as CUmemorytype;
+impl CUmem_advise_enum {
+ pub const CU_MEM_ADVISE_SET_READ_MOSTLY: CUmem_advise_enum = CUmem_advise_enum(1);
+}
+impl CUmem_advise_enum {
+ pub const CU_MEM_ADVISE_UNSET_READ_MOSTLY: CUmem_advise_enum = CUmem_advise_enum(2);
+}
+impl CUmem_advise_enum {
+ pub const CU_MEM_ADVISE_SET_PREFERRED_LOCATION: CUmem_advise_enum = CUmem_advise_enum(3);
+}
+impl CUmem_advise_enum {
+ pub const CU_MEM_ADVISE_UNSET_PREFERRED_LOCATION: CUmem_advise_enum = CUmem_advise_enum(4);
+}
+impl CUmem_advise_enum {
+ pub const CU_MEM_ADVISE_SET_ACCESSED_BY: CUmem_advise_enum = CUmem_advise_enum(5);
+}
+impl CUmem_advise_enum {
+ pub const CU_MEM_ADVISE_UNSET_ACCESSED_BY: CUmem_advise_enum = CUmem_advise_enum(6);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUmem_advise_enum(pub ::std::os::raw::c_uint);
+pub use self::CUmem_advise_enum as CUmem_advise;
+impl CUmem_range_attribute_enum {
+ pub const CU_MEM_RANGE_ATTRIBUTE_READ_MOSTLY: CUmem_range_attribute_enum =
+ CUmem_range_attribute_enum(1);
+}
+impl CUmem_range_attribute_enum {
+ pub const CU_MEM_RANGE_ATTRIBUTE_PREFERRED_LOCATION: CUmem_range_attribute_enum =
+ CUmem_range_attribute_enum(2);
+}
+impl CUmem_range_attribute_enum {
+ pub const CU_MEM_RANGE_ATTRIBUTE_ACCESSED_BY: CUmem_range_attribute_enum =
+ CUmem_range_attribute_enum(3);
+}
+impl CUmem_range_attribute_enum {
+ pub const CU_MEM_RANGE_ATTRIBUTE_LAST_PREFETCH_LOCATION: CUmem_range_attribute_enum =
+ CUmem_range_attribute_enum(4);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUmem_range_attribute_enum(pub ::std::os::raw::c_uint);
+pub use self::CUmem_range_attribute_enum as CUmem_range_attribute;
+impl CUjit_option_enum {
+ pub const CU_JIT_MAX_REGISTERS: CUjit_option_enum = CUjit_option_enum(0);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_THREADS_PER_BLOCK: CUjit_option_enum = CUjit_option_enum(1);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_WALL_TIME: CUjit_option_enum = CUjit_option_enum(2);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_INFO_LOG_BUFFER: CUjit_option_enum = CUjit_option_enum(3);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_INFO_LOG_BUFFER_SIZE_BYTES: CUjit_option_enum = CUjit_option_enum(4);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_ERROR_LOG_BUFFER: CUjit_option_enum = CUjit_option_enum(5);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_ERROR_LOG_BUFFER_SIZE_BYTES: CUjit_option_enum = CUjit_option_enum(6);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_OPTIMIZATION_LEVEL: CUjit_option_enum = CUjit_option_enum(7);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_TARGET_FROM_CUCONTEXT: CUjit_option_enum = CUjit_option_enum(8);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_TARGET: CUjit_option_enum = CUjit_option_enum(9);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_FALLBACK_STRATEGY: CUjit_option_enum = CUjit_option_enum(10);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_GENERATE_DEBUG_INFO: CUjit_option_enum = CUjit_option_enum(11);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_LOG_VERBOSE: CUjit_option_enum = CUjit_option_enum(12);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_GENERATE_LINE_INFO: CUjit_option_enum = CUjit_option_enum(13);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_CACHE_MODE: CUjit_option_enum = CUjit_option_enum(14);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_NEW_SM3X_OPT: CUjit_option_enum = CUjit_option_enum(15);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_FAST_COMPILE: CUjit_option_enum = CUjit_option_enum(16);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_GLOBAL_SYMBOL_NAMES: CUjit_option_enum = CUjit_option_enum(17);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_GLOBAL_SYMBOL_ADDRESSES: CUjit_option_enum = CUjit_option_enum(18);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_GLOBAL_SYMBOL_COUNT: CUjit_option_enum = CUjit_option_enum(19);
+}
+impl CUjit_option_enum {
+ pub const CU_JIT_NUM_OPTIONS: CUjit_option_enum = CUjit_option_enum(20);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUjit_option_enum(pub ::std::os::raw::c_uint);
+pub use self::CUjit_option_enum as CUjit_option;
+impl CUjitInputType_enum {
+ pub const CU_JIT_INPUT_CUBIN: CUjitInputType_enum = CUjitInputType_enum(0);
+}
+impl CUjitInputType_enum {
+ pub const CU_JIT_INPUT_PTX: CUjitInputType_enum = CUjitInputType_enum(1);
+}
+impl CUjitInputType_enum {
+ pub const CU_JIT_INPUT_FATBINARY: CUjitInputType_enum = CUjitInputType_enum(2);
+}
+impl CUjitInputType_enum {
+ pub const CU_JIT_INPUT_OBJECT: CUjitInputType_enum = CUjitInputType_enum(3);
+}
+impl CUjitInputType_enum {
+ pub const CU_JIT_INPUT_LIBRARY: CUjitInputType_enum = CUjitInputType_enum(4);
+}
+impl CUjitInputType_enum {
+ pub const CU_JIT_NUM_INPUT_TYPES: CUjitInputType_enum = CUjitInputType_enum(5);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUjitInputType_enum(pub ::std::os::raw::c_uint);
+pub use self::CUjitInputType_enum as CUjitInputType;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUlinkState_st {
+ _unused: [u8; 0],
+}
+pub type CUlinkState = *mut CUlinkState_st;
+impl CUlimit_enum {
+ pub const CU_LIMIT_STACK_SIZE: CUlimit_enum = CUlimit_enum(0);
+}
+impl CUlimit_enum {
+ pub const CU_LIMIT_PRINTF_FIFO_SIZE: CUlimit_enum = CUlimit_enum(1);
+}
+impl CUlimit_enum {
+ pub const CU_LIMIT_MALLOC_HEAP_SIZE: CUlimit_enum = CUlimit_enum(2);
+}
+impl CUlimit_enum {
+ pub const CU_LIMIT_DEV_RUNTIME_SYNC_DEPTH: CUlimit_enum = CUlimit_enum(3);
+}
+impl CUlimit_enum {
+ pub const CU_LIMIT_DEV_RUNTIME_PENDING_LAUNCH_COUNT: CUlimit_enum = CUlimit_enum(4);
+}
+impl CUlimit_enum {
+ pub const CU_LIMIT_MAX_L2_FETCH_GRANULARITY: CUlimit_enum = CUlimit_enum(5);
+}
+impl CUlimit_enum {
+ pub const CU_LIMIT_PERSISTING_L2_CACHE_SIZE: CUlimit_enum = CUlimit_enum(6);
+}
+impl CUlimit_enum {
+ pub const CU_LIMIT_MAX: CUlimit_enum = CUlimit_enum(7);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUlimit_enum(pub ::std::os::raw::c_uint);
+pub use self::CUlimit_enum as CUlimit;
+impl CUresourcetype_enum {
+ pub const CU_RESOURCE_TYPE_ARRAY: CUresourcetype_enum = CUresourcetype_enum(0);
+}
+impl CUresourcetype_enum {
+ pub const CU_RESOURCE_TYPE_MIPMAPPED_ARRAY: CUresourcetype_enum = CUresourcetype_enum(1);
+}
+impl CUresourcetype_enum {
+ pub const CU_RESOURCE_TYPE_LINEAR: CUresourcetype_enum = CUresourcetype_enum(2);
+}
+impl CUresourcetype_enum {
+ pub const CU_RESOURCE_TYPE_PITCH2D: CUresourcetype_enum = CUresourcetype_enum(3);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUresourcetype_enum(pub ::std::os::raw::c_uint);
+pub use self::CUresourcetype_enum as CUresourcetype;
+pub type CUhostFn =
+ ::std::option::Option<unsafe extern "C" fn(userData: *mut ::std::os::raw::c_void)>;
+impl CUaccessProperty_enum {
+ pub const CU_ACCESS_PROPERTY_NORMAL: CUaccessProperty_enum = CUaccessProperty_enum(0);
+}
+impl CUaccessProperty_enum {
+ pub const CU_ACCESS_PROPERTY_STREAMING: CUaccessProperty_enum = CUaccessProperty_enum(1);
+}
+impl CUaccessProperty_enum {
+ pub const CU_ACCESS_PROPERTY_PERSISTING: CUaccessProperty_enum = CUaccessProperty_enum(2);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUaccessProperty_enum(pub ::std::os::raw::c_uint);
+pub use self::CUaccessProperty_enum as CUaccessProperty;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUaccessPolicyWindow_st {
+ pub base_ptr: *mut ::std::os::raw::c_void,
+ pub num_bytes: usize,
+ pub hitRatio: f32,
+ pub hitProp: CUaccessProperty,
+ pub missProp: CUaccessProperty,
+}
+pub type CUaccessPolicyWindow = CUaccessPolicyWindow_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_KERNEL_NODE_PARAMS_st {
+ pub func: CUfunction,
+ pub gridDimX: ::std::os::raw::c_uint,
+ pub gridDimY: ::std::os::raw::c_uint,
+ pub gridDimZ: ::std::os::raw::c_uint,
+ pub blockDimX: ::std::os::raw::c_uint,
+ pub blockDimY: ::std::os::raw::c_uint,
+ pub blockDimZ: ::std::os::raw::c_uint,
+ pub sharedMemBytes: ::std::os::raw::c_uint,
+ pub kernelParams: *mut *mut ::std::os::raw::c_void,
+ pub extra: *mut *mut ::std::os::raw::c_void,
+}
+pub type CUDA_KERNEL_NODE_PARAMS = CUDA_KERNEL_NODE_PARAMS_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_MEMSET_NODE_PARAMS_st {
+ pub dst: CUdeviceptr,
+ pub pitch: usize,
+ pub value: ::std::os::raw::c_uint,
+ pub elementSize: ::std::os::raw::c_uint,
+ pub width: usize,
+ pub height: usize,
+}
+pub type CUDA_MEMSET_NODE_PARAMS = CUDA_MEMSET_NODE_PARAMS_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_HOST_NODE_PARAMS_st {
+ pub fn_: CUhostFn,
+ pub userData: *mut ::std::os::raw::c_void,
+}
+pub type CUDA_HOST_NODE_PARAMS = CUDA_HOST_NODE_PARAMS_st;
+impl CUgraphNodeType_enum {
+ pub const CU_GRAPH_NODE_TYPE_KERNEL: CUgraphNodeType_enum = CUgraphNodeType_enum(0);
+}
+impl CUgraphNodeType_enum {
+ pub const CU_GRAPH_NODE_TYPE_MEMCPY: CUgraphNodeType_enum = CUgraphNodeType_enum(1);
+}
+impl CUgraphNodeType_enum {
+ pub const CU_GRAPH_NODE_TYPE_MEMSET: CUgraphNodeType_enum = CUgraphNodeType_enum(2);
+}
+impl CUgraphNodeType_enum {
+ pub const CU_GRAPH_NODE_TYPE_HOST: CUgraphNodeType_enum = CUgraphNodeType_enum(3);
+}
+impl CUgraphNodeType_enum {
+ pub const CU_GRAPH_NODE_TYPE_GRAPH: CUgraphNodeType_enum = CUgraphNodeType_enum(4);
+}
+impl CUgraphNodeType_enum {
+ pub const CU_GRAPH_NODE_TYPE_EMPTY: CUgraphNodeType_enum = CUgraphNodeType_enum(5);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUgraphNodeType_enum(pub ::std::os::raw::c_uint);
+pub use self::CUgraphNodeType_enum as CUgraphNodeType;
+impl CUsynchronizationPolicy_enum {
+ pub const CU_SYNC_POLICY_AUTO: CUsynchronizationPolicy_enum = CUsynchronizationPolicy_enum(1);
+}
+impl CUsynchronizationPolicy_enum {
+ pub const CU_SYNC_POLICY_SPIN: CUsynchronizationPolicy_enum = CUsynchronizationPolicy_enum(2);
+}
+impl CUsynchronizationPolicy_enum {
+ pub const CU_SYNC_POLICY_YIELD: CUsynchronizationPolicy_enum = CUsynchronizationPolicy_enum(3);
+}
+impl CUsynchronizationPolicy_enum {
+ pub const CU_SYNC_POLICY_BLOCKING_SYNC: CUsynchronizationPolicy_enum =
+ CUsynchronizationPolicy_enum(4);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUsynchronizationPolicy_enum(pub ::std::os::raw::c_uint);
+pub use self::CUsynchronizationPolicy_enum as CUsynchronizationPolicy;
+impl CUkernelNodeAttrID_enum {
+ pub const CU_KERNEL_NODE_ATTRIBUTE_ACCESS_POLICY_WINDOW: CUkernelNodeAttrID_enum =
+ CUkernelNodeAttrID_enum(1);
+}
+impl CUkernelNodeAttrID_enum {
+ pub const CU_KERNEL_NODE_ATTRIBUTE_COOPERATIVE: CUkernelNodeAttrID_enum =
+ CUkernelNodeAttrID_enum(2);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUkernelNodeAttrID_enum(pub ::std::os::raw::c_uint);
+pub use self::CUkernelNodeAttrID_enum as CUkernelNodeAttrID;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union CUkernelNodeAttrValue_union {
+ pub accessPolicyWindow: CUaccessPolicyWindow,
+ pub cooperative: ::std::os::raw::c_int,
+ _bindgen_union_align: [u64; 4usize],
+}
+pub type CUkernelNodeAttrValue = CUkernelNodeAttrValue_union;
+impl CUstreamCaptureStatus_enum {
+ pub const CU_STREAM_CAPTURE_STATUS_NONE: CUstreamCaptureStatus_enum =
+ CUstreamCaptureStatus_enum(0);
+}
+impl CUstreamCaptureStatus_enum {
+ pub const CU_STREAM_CAPTURE_STATUS_ACTIVE: CUstreamCaptureStatus_enum =
+ CUstreamCaptureStatus_enum(1);
+}
+impl CUstreamCaptureStatus_enum {
+ pub const CU_STREAM_CAPTURE_STATUS_INVALIDATED: CUstreamCaptureStatus_enum =
+ CUstreamCaptureStatus_enum(2);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUstreamCaptureStatus_enum(pub ::std::os::raw::c_uint);
+pub use self::CUstreamCaptureStatus_enum as CUstreamCaptureStatus;
+impl CUstreamCaptureMode_enum {
+ pub const CU_STREAM_CAPTURE_MODE_GLOBAL: CUstreamCaptureMode_enum = CUstreamCaptureMode_enum(0);
+}
+impl CUstreamCaptureMode_enum {
+ pub const CU_STREAM_CAPTURE_MODE_THREAD_LOCAL: CUstreamCaptureMode_enum =
+ CUstreamCaptureMode_enum(1);
+}
+impl CUstreamCaptureMode_enum {
+ pub const CU_STREAM_CAPTURE_MODE_RELAXED: CUstreamCaptureMode_enum =
+ CUstreamCaptureMode_enum(2);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUstreamCaptureMode_enum(pub ::std::os::raw::c_uint);
+pub use self::CUstreamCaptureMode_enum as CUstreamCaptureMode;
+impl CUstreamAttrID_enum {
+ pub const CU_STREAM_ATTRIBUTE_ACCESS_POLICY_WINDOW: CUstreamAttrID_enum =
+ CUstreamAttrID_enum(1);
+}
+impl CUstreamAttrID_enum {
+ pub const CU_STREAM_ATTRIBUTE_SYNCHRONIZATION_POLICY: CUstreamAttrID_enum =
+ CUstreamAttrID_enum(3);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUstreamAttrID_enum(pub ::std::os::raw::c_uint);
+pub use self::CUstreamAttrID_enum as CUstreamAttrID;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union CUstreamAttrValue_union {
+ pub accessPolicyWindow: CUaccessPolicyWindow,
+ pub syncPolicy: CUsynchronizationPolicy,
+ _bindgen_union_align: [u64; 4usize],
+}
+pub type CUstreamAttrValue = CUstreamAttrValue_union;
+impl cudaError_enum {
+ pub const CUDA_SUCCESS: cudaError_enum = cudaError_enum(0);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_INVALID_VALUE: cudaError_enum = cudaError_enum(1);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_OUT_OF_MEMORY: cudaError_enum = cudaError_enum(2);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_NOT_INITIALIZED: cudaError_enum = cudaError_enum(3);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_DEINITIALIZED: cudaError_enum = cudaError_enum(4);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_PROFILER_DISABLED: cudaError_enum = cudaError_enum(5);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_PROFILER_NOT_INITIALIZED: cudaError_enum = cudaError_enum(6);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_PROFILER_ALREADY_STARTED: cudaError_enum = cudaError_enum(7);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_PROFILER_ALREADY_STOPPED: cudaError_enum = cudaError_enum(8);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_NO_DEVICE: cudaError_enum = cudaError_enum(100);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_INVALID_DEVICE: cudaError_enum = cudaError_enum(101);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_INVALID_IMAGE: cudaError_enum = cudaError_enum(200);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_INVALID_CONTEXT: cudaError_enum = cudaError_enum(201);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_CONTEXT_ALREADY_CURRENT: cudaError_enum = cudaError_enum(202);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_MAP_FAILED: cudaError_enum = cudaError_enum(205);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_UNMAP_FAILED: cudaError_enum = cudaError_enum(206);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_ARRAY_IS_MAPPED: cudaError_enum = cudaError_enum(207);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_ALREADY_MAPPED: cudaError_enum = cudaError_enum(208);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_NO_BINARY_FOR_GPU: cudaError_enum = cudaError_enum(209);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_ALREADY_ACQUIRED: cudaError_enum = cudaError_enum(210);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_NOT_MAPPED: cudaError_enum = cudaError_enum(211);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_NOT_MAPPED_AS_ARRAY: cudaError_enum = cudaError_enum(212);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_NOT_MAPPED_AS_POINTER: cudaError_enum = cudaError_enum(213);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_ECC_UNCORRECTABLE: cudaError_enum = cudaError_enum(214);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_UNSUPPORTED_LIMIT: cudaError_enum = cudaError_enum(215);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_CONTEXT_ALREADY_IN_USE: cudaError_enum = cudaError_enum(216);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_PEER_ACCESS_UNSUPPORTED: cudaError_enum = cudaError_enum(217);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_INVALID_PTX: cudaError_enum = cudaError_enum(218);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_INVALID_GRAPHICS_CONTEXT: cudaError_enum = cudaError_enum(219);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_NVLINK_UNCORRECTABLE: cudaError_enum = cudaError_enum(220);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_JIT_COMPILER_NOT_FOUND: cudaError_enum = cudaError_enum(221);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_INVALID_SOURCE: cudaError_enum = cudaError_enum(300);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_FILE_NOT_FOUND: cudaError_enum = cudaError_enum(301);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND: cudaError_enum = cudaError_enum(302);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_SHARED_OBJECT_INIT_FAILED: cudaError_enum = cudaError_enum(303);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_OPERATING_SYSTEM: cudaError_enum = cudaError_enum(304);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_INVALID_HANDLE: cudaError_enum = cudaError_enum(400);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_ILLEGAL_STATE: cudaError_enum = cudaError_enum(401);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_NOT_FOUND: cudaError_enum = cudaError_enum(500);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_NOT_READY: cudaError_enum = cudaError_enum(600);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_ILLEGAL_ADDRESS: cudaError_enum = cudaError_enum(700);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES: cudaError_enum = cudaError_enum(701);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_LAUNCH_TIMEOUT: cudaError_enum = cudaError_enum(702);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING: cudaError_enum = cudaError_enum(703);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_PEER_ACCESS_ALREADY_ENABLED: cudaError_enum = cudaError_enum(704);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_PEER_ACCESS_NOT_ENABLED: cudaError_enum = cudaError_enum(705);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_PRIMARY_CONTEXT_ACTIVE: cudaError_enum = cudaError_enum(708);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_CONTEXT_IS_DESTROYED: cudaError_enum = cudaError_enum(709);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_ASSERT: cudaError_enum = cudaError_enum(710);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_TOO_MANY_PEERS: cudaError_enum = cudaError_enum(711);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED: cudaError_enum = cudaError_enum(712);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_HOST_MEMORY_NOT_REGISTERED: cudaError_enum = cudaError_enum(713);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_HARDWARE_STACK_ERROR: cudaError_enum = cudaError_enum(714);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_ILLEGAL_INSTRUCTION: cudaError_enum = cudaError_enum(715);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_MISALIGNED_ADDRESS: cudaError_enum = cudaError_enum(716);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_INVALID_ADDRESS_SPACE: cudaError_enum = cudaError_enum(717);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_INVALID_PC: cudaError_enum = cudaError_enum(718);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_LAUNCH_FAILED: cudaError_enum = cudaError_enum(719);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_COOPERATIVE_LAUNCH_TOO_LARGE: cudaError_enum = cudaError_enum(720);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_NOT_PERMITTED: cudaError_enum = cudaError_enum(800);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_NOT_SUPPORTED: cudaError_enum = cudaError_enum(801);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_SYSTEM_NOT_READY: cudaError_enum = cudaError_enum(802);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_SYSTEM_DRIVER_MISMATCH: cudaError_enum = cudaError_enum(803);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_COMPAT_NOT_SUPPORTED_ON_DEVICE: cudaError_enum = cudaError_enum(804);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_STREAM_CAPTURE_UNSUPPORTED: cudaError_enum = cudaError_enum(900);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_STREAM_CAPTURE_INVALIDATED: cudaError_enum = cudaError_enum(901);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_STREAM_CAPTURE_MERGE: cudaError_enum = cudaError_enum(902);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_STREAM_CAPTURE_UNMATCHED: cudaError_enum = cudaError_enum(903);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_STREAM_CAPTURE_UNJOINED: cudaError_enum = cudaError_enum(904);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_STREAM_CAPTURE_ISOLATION: cudaError_enum = cudaError_enum(905);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_STREAM_CAPTURE_IMPLICIT: cudaError_enum = cudaError_enum(906);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_CAPTURED_EVENT: cudaError_enum = cudaError_enum(907);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_STREAM_CAPTURE_WRONG_THREAD: cudaError_enum = cudaError_enum(908);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_TIMEOUT: cudaError_enum = cudaError_enum(909);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_GRAPH_EXEC_UPDATE_FAILURE: cudaError_enum = cudaError_enum(910);
+}
+impl cudaError_enum {
+ pub const CUDA_ERROR_UNKNOWN: cudaError_enum = cudaError_enum(999);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct cudaError_enum(pub ::std::os::raw::c_uint);
+pub use self::cudaError_enum as CUresult;
+impl CUdevice_P2PAttribute_enum {
+ pub const CU_DEVICE_P2P_ATTRIBUTE_PERFORMANCE_RANK: CUdevice_P2PAttribute_enum =
+ CUdevice_P2PAttribute_enum(1);
+}
+impl CUdevice_P2PAttribute_enum {
+ pub const CU_DEVICE_P2P_ATTRIBUTE_ACCESS_SUPPORTED: CUdevice_P2PAttribute_enum =
+ CUdevice_P2PAttribute_enum(2);
+}
+impl CUdevice_P2PAttribute_enum {
+ pub const CU_DEVICE_P2P_ATTRIBUTE_NATIVE_ATOMIC_SUPPORTED: CUdevice_P2PAttribute_enum =
+ CUdevice_P2PAttribute_enum(3);
+}
+impl CUdevice_P2PAttribute_enum {
+ pub const CU_DEVICE_P2P_ATTRIBUTE_ACCESS_ACCESS_SUPPORTED: CUdevice_P2PAttribute_enum =
+ CUdevice_P2PAttribute_enum(4);
+}
+impl CUdevice_P2PAttribute_enum {
+ pub const CU_DEVICE_P2P_ATTRIBUTE_CUDA_ARRAY_ACCESS_SUPPORTED: CUdevice_P2PAttribute_enum =
+ CUdevice_P2PAttribute_enum(4);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUdevice_P2PAttribute_enum(pub ::std::os::raw::c_uint);
+pub use self::CUdevice_P2PAttribute_enum as CUdevice_P2PAttribute;
+pub type CUstreamCallback = ::std::option::Option<
+ unsafe extern "C" fn(
+ hStream: CUstream,
+ status: CUresult,
+ userData: *mut ::std::os::raw::c_void,
+ ),
+>;
+pub type CUoccupancyB2DSize =
+ ::std::option::Option<unsafe extern "C" fn(blockSize: ::std::os::raw::c_int) -> usize>;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_MEMCPY2D_st {
+ pub srcXInBytes: usize,
+ pub srcY: usize,
+ pub srcMemoryType: CUmemorytype,
+ pub srcHost: *const ::std::os::raw::c_void,
+ pub srcDevice: CUdeviceptr,
+ pub srcArray: CUarray,
+ pub srcPitch: usize,
+ pub dstXInBytes: usize,
+ pub dstY: usize,
+ pub dstMemoryType: CUmemorytype,
+ pub dstHost: *mut ::std::os::raw::c_void,
+ pub dstDevice: CUdeviceptr,
+ pub dstArray: CUarray,
+ pub dstPitch: usize,
+ pub WidthInBytes: usize,
+ pub Height: usize,
+}
+pub type CUDA_MEMCPY2D = CUDA_MEMCPY2D_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_MEMCPY3D_st {
+ pub srcXInBytes: usize,
+ pub srcY: usize,
+ pub srcZ: usize,
+ pub srcLOD: usize,
+ pub srcMemoryType: CUmemorytype,
+ pub srcHost: *const ::std::os::raw::c_void,
+ pub srcDevice: CUdeviceptr,
+ pub srcArray: CUarray,
+ pub reserved0: *mut ::std::os::raw::c_void,
+ pub srcPitch: usize,
+ pub srcHeight: usize,
+ pub dstXInBytes: usize,
+ pub dstY: usize,
+ pub dstZ: usize,
+ pub dstLOD: usize,
+ pub dstMemoryType: CUmemorytype,
+ pub dstHost: *mut ::std::os::raw::c_void,
+ pub dstDevice: CUdeviceptr,
+ pub dstArray: CUarray,
+ pub reserved1: *mut ::std::os::raw::c_void,
+ pub dstPitch: usize,
+ pub dstHeight: usize,
+ pub WidthInBytes: usize,
+ pub Height: usize,
+ pub Depth: usize,
+}
+pub type CUDA_MEMCPY3D = CUDA_MEMCPY3D_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_MEMCPY3D_PEER_st {
+ pub srcXInBytes: usize,
+ pub srcY: usize,
+ pub srcZ: usize,
+ pub srcLOD: usize,
+ pub srcMemoryType: CUmemorytype,
+ pub srcHost: *const ::std::os::raw::c_void,
+ pub srcDevice: CUdeviceptr,
+ pub srcArray: CUarray,
+ pub srcContext: CUcontext,
+ pub srcPitch: usize,
+ pub srcHeight: usize,
+ pub dstXInBytes: usize,
+ pub dstY: usize,
+ pub dstZ: usize,
+ pub dstLOD: usize,
+ pub dstMemoryType: CUmemorytype,
+ pub dstHost: *mut ::std::os::raw::c_void,
+ pub dstDevice: CUdeviceptr,
+ pub dstArray: CUarray,
+ pub dstContext: CUcontext,
+ pub dstPitch: usize,
+ pub dstHeight: usize,
+ pub WidthInBytes: usize,
+ pub Height: usize,
+ pub Depth: usize,
+}
+pub type CUDA_MEMCPY3D_PEER = CUDA_MEMCPY3D_PEER_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_ARRAY_DESCRIPTOR_st {
+ pub Width: usize,
+ pub Height: usize,
+ pub Format: CUarray_format,
+ pub NumChannels: ::std::os::raw::c_uint,
+}
+pub type CUDA_ARRAY_DESCRIPTOR = CUDA_ARRAY_DESCRIPTOR_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_ARRAY3D_DESCRIPTOR_st {
+ pub Width: usize,
+ pub Height: usize,
+ pub Depth: usize,
+ pub Format: CUarray_format,
+ pub NumChannels: ::std::os::raw::c_uint,
+ pub Flags: ::std::os::raw::c_uint,
+}
+pub type CUDA_ARRAY3D_DESCRIPTOR = CUDA_ARRAY3D_DESCRIPTOR_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_RESOURCE_DESC_st {
+ pub resType: CUresourcetype,
+ pub res: CUDA_RESOURCE_DESC_st__bindgen_ty_1,
+ pub flags: ::std::os::raw::c_uint,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union CUDA_RESOURCE_DESC_st__bindgen_ty_1 {
+ pub array: CUDA_RESOURCE_DESC_st__bindgen_ty_1__bindgen_ty_1,
+ pub mipmap: CUDA_RESOURCE_DESC_st__bindgen_ty_1__bindgen_ty_2,
+ pub linear: CUDA_RESOURCE_DESC_st__bindgen_ty_1__bindgen_ty_3,
+ pub pitch2D: CUDA_RESOURCE_DESC_st__bindgen_ty_1__bindgen_ty_4,
+ pub reserved: CUDA_RESOURCE_DESC_st__bindgen_ty_1__bindgen_ty_5,
+ _bindgen_union_align: [u64; 16usize],
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_RESOURCE_DESC_st__bindgen_ty_1__bindgen_ty_1 {
+ pub hArray: CUarray,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_RESOURCE_DESC_st__bindgen_ty_1__bindgen_ty_2 {
+ pub hMipmappedArray: CUmipmappedArray,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_RESOURCE_DESC_st__bindgen_ty_1__bindgen_ty_3 {
+ pub devPtr: CUdeviceptr,
+ pub format: CUarray_format,
+ pub numChannels: ::std::os::raw::c_uint,
+ pub sizeInBytes: usize,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_RESOURCE_DESC_st__bindgen_ty_1__bindgen_ty_4 {
+ pub devPtr: CUdeviceptr,
+ pub format: CUarray_format,
+ pub numChannels: ::std::os::raw::c_uint,
+ pub width: usize,
+ pub height: usize,
+ pub pitchInBytes: usize,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_RESOURCE_DESC_st__bindgen_ty_1__bindgen_ty_5 {
+ pub reserved: [::std::os::raw::c_int; 32usize],
+}
+pub type CUDA_RESOURCE_DESC = CUDA_RESOURCE_DESC_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_TEXTURE_DESC_st {
+ pub addressMode: [CUaddress_mode; 3usize],
+ pub filterMode: CUfilter_mode,
+ pub flags: ::std::os::raw::c_uint,
+ pub maxAnisotropy: ::std::os::raw::c_uint,
+ pub mipmapFilterMode: CUfilter_mode,
+ pub mipmapLevelBias: f32,
+ pub minMipmapLevelClamp: f32,
+ pub maxMipmapLevelClamp: f32,
+ pub borderColor: [f32; 4usize],
+ pub reserved: [::std::os::raw::c_int; 12usize],
+}
+pub type CUDA_TEXTURE_DESC = CUDA_TEXTURE_DESC_st;
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_NONE: CUresourceViewFormat_enum = CUresourceViewFormat_enum(0);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_UINT_1X8: CUresourceViewFormat_enum = CUresourceViewFormat_enum(1);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_UINT_2X8: CUresourceViewFormat_enum = CUresourceViewFormat_enum(2);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_UINT_4X8: CUresourceViewFormat_enum = CUresourceViewFormat_enum(3);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_SINT_1X8: CUresourceViewFormat_enum = CUresourceViewFormat_enum(4);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_SINT_2X8: CUresourceViewFormat_enum = CUresourceViewFormat_enum(5);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_SINT_4X8: CUresourceViewFormat_enum = CUresourceViewFormat_enum(6);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_UINT_1X16: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(7);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_UINT_2X16: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(8);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_UINT_4X16: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(9);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_SINT_1X16: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(10);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_SINT_2X16: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(11);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_SINT_4X16: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(12);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_UINT_1X32: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(13);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_UINT_2X32: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(14);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_UINT_4X32: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(15);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_SINT_1X32: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(16);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_SINT_2X32: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(17);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_SINT_4X32: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(18);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_FLOAT_1X16: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(19);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_FLOAT_2X16: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(20);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_FLOAT_4X16: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(21);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_FLOAT_1X32: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(22);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_FLOAT_2X32: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(23);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_FLOAT_4X32: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(24);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_UNSIGNED_BC1: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(25);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_UNSIGNED_BC2: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(26);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_UNSIGNED_BC3: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(27);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_UNSIGNED_BC4: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(28);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_SIGNED_BC4: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(29);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_UNSIGNED_BC5: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(30);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_SIGNED_BC5: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(31);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_UNSIGNED_BC6H: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(32);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_SIGNED_BC6H: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(33);
+}
+impl CUresourceViewFormat_enum {
+ pub const CU_RES_VIEW_FORMAT_UNSIGNED_BC7: CUresourceViewFormat_enum =
+ CUresourceViewFormat_enum(34);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUresourceViewFormat_enum(pub ::std::os::raw::c_uint);
+pub use self::CUresourceViewFormat_enum as CUresourceViewFormat;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_RESOURCE_VIEW_DESC_st {
+ pub format: CUresourceViewFormat,
+ pub width: usize,
+ pub height: usize,
+ pub depth: usize,
+ pub firstMipmapLevel: ::std::os::raw::c_uint,
+ pub lastMipmapLevel: ::std::os::raw::c_uint,
+ pub firstLayer: ::std::os::raw::c_uint,
+ pub lastLayer: ::std::os::raw::c_uint,
+ pub reserved: [::std::os::raw::c_uint; 16usize],
+}
+pub type CUDA_RESOURCE_VIEW_DESC = CUDA_RESOURCE_VIEW_DESC_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_LAUNCH_PARAMS_st {
+ pub function: CUfunction,
+ pub gridDimX: ::std::os::raw::c_uint,
+ pub gridDimY: ::std::os::raw::c_uint,
+ pub gridDimZ: ::std::os::raw::c_uint,
+ pub blockDimX: ::std::os::raw::c_uint,
+ pub blockDimY: ::std::os::raw::c_uint,
+ pub blockDimZ: ::std::os::raw::c_uint,
+ pub sharedMemBytes: ::std::os::raw::c_uint,
+ pub hStream: CUstream,
+ pub kernelParams: *mut *mut ::std::os::raw::c_void,
+}
+pub type CUDA_LAUNCH_PARAMS = CUDA_LAUNCH_PARAMS_st;
+impl CUexternalMemoryHandleType_enum {
+ pub const CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD: CUexternalMemoryHandleType_enum =
+ CUexternalMemoryHandleType_enum(1);
+}
+impl CUexternalMemoryHandleType_enum {
+ pub const CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32: CUexternalMemoryHandleType_enum =
+ CUexternalMemoryHandleType_enum(2);
+}
+impl CUexternalMemoryHandleType_enum {
+ pub const CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT: CUexternalMemoryHandleType_enum =
+ CUexternalMemoryHandleType_enum(3);
+}
+impl CUexternalMemoryHandleType_enum {
+ pub const CU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP: CUexternalMemoryHandleType_enum =
+ CUexternalMemoryHandleType_enum(4);
+}
+impl CUexternalMemoryHandleType_enum {
+ pub const CU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE: CUexternalMemoryHandleType_enum =
+ CUexternalMemoryHandleType_enum(5);
+}
+impl CUexternalMemoryHandleType_enum {
+ pub const CU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_RESOURCE: CUexternalMemoryHandleType_enum =
+ CUexternalMemoryHandleType_enum(6);
+}
+impl CUexternalMemoryHandleType_enum {
+ pub const CU_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_RESOURCE_KMT: CUexternalMemoryHandleType_enum =
+ CUexternalMemoryHandleType_enum(7);
+}
+impl CUexternalMemoryHandleType_enum {
+ pub const CU_EXTERNAL_MEMORY_HANDLE_TYPE_NVSCIBUF: CUexternalMemoryHandleType_enum =
+ CUexternalMemoryHandleType_enum(8);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUexternalMemoryHandleType_enum(pub ::std::os::raw::c_uint);
+pub use self::CUexternalMemoryHandleType_enum as CUexternalMemoryHandleType;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_EXTERNAL_MEMORY_HANDLE_DESC_st {
+ pub type_: CUexternalMemoryHandleType,
+ pub handle: CUDA_EXTERNAL_MEMORY_HANDLE_DESC_st__bindgen_ty_1,
+ pub size: ::std::os::raw::c_ulonglong,
+ pub flags: ::std::os::raw::c_uint,
+ pub reserved: [::std::os::raw::c_uint; 16usize],
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union CUDA_EXTERNAL_MEMORY_HANDLE_DESC_st__bindgen_ty_1 {
+ pub fd: ::std::os::raw::c_int,
+ pub win32: CUDA_EXTERNAL_MEMORY_HANDLE_DESC_st__bindgen_ty_1__bindgen_ty_1,
+ pub nvSciBufObject: *const ::std::os::raw::c_void,
+ _bindgen_union_align: [u64; 2usize],
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_EXTERNAL_MEMORY_HANDLE_DESC_st__bindgen_ty_1__bindgen_ty_1 {
+ pub handle: *mut ::std::os::raw::c_void,
+ pub name: *const ::std::os::raw::c_void,
+}
+pub type CUDA_EXTERNAL_MEMORY_HANDLE_DESC = CUDA_EXTERNAL_MEMORY_HANDLE_DESC_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_EXTERNAL_MEMORY_BUFFER_DESC_st {
+ pub offset: ::std::os::raw::c_ulonglong,
+ pub size: ::std::os::raw::c_ulonglong,
+ pub flags: ::std::os::raw::c_uint,
+ pub reserved: [::std::os::raw::c_uint; 16usize],
+}
+pub type CUDA_EXTERNAL_MEMORY_BUFFER_DESC = CUDA_EXTERNAL_MEMORY_BUFFER_DESC_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC_st {
+ pub offset: ::std::os::raw::c_ulonglong,
+ pub arrayDesc: CUDA_ARRAY3D_DESCRIPTOR,
+ pub numLevels: ::std::os::raw::c_uint,
+ pub reserved: [::std::os::raw::c_uint; 16usize],
+}
+pub type CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC = CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC_st;
+impl CUexternalSemaphoreHandleType_enum {
+ pub const CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD: CUexternalSemaphoreHandleType_enum =
+ CUexternalSemaphoreHandleType_enum(1);
+}
+impl CUexternalSemaphoreHandleType_enum {
+ pub const CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32: CUexternalSemaphoreHandleType_enum =
+ CUexternalSemaphoreHandleType_enum(2);
+}
+impl CUexternalSemaphoreHandleType_enum {
+ pub const CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT:
+ CUexternalSemaphoreHandleType_enum = CUexternalSemaphoreHandleType_enum(3);
+}
+impl CUexternalSemaphoreHandleType_enum {
+ pub const CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE: CUexternalSemaphoreHandleType_enum =
+ CUexternalSemaphoreHandleType_enum(4);
+}
+impl CUexternalSemaphoreHandleType_enum {
+ pub const CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_FENCE: CUexternalSemaphoreHandleType_enum =
+ CUexternalSemaphoreHandleType_enum(5);
+}
+impl CUexternalSemaphoreHandleType_enum {
+ pub const CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_NVSCISYNC: CUexternalSemaphoreHandleType_enum =
+ CUexternalSemaphoreHandleType_enum(6);
+}
+impl CUexternalSemaphoreHandleType_enum {
+ pub const CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_KEYED_MUTEX:
+ CUexternalSemaphoreHandleType_enum = CUexternalSemaphoreHandleType_enum(7);
+}
+impl CUexternalSemaphoreHandleType_enum {
+ pub const CU_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_KEYED_MUTEX_KMT:
+ CUexternalSemaphoreHandleType_enum = CUexternalSemaphoreHandleType_enum(8);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUexternalSemaphoreHandleType_enum(pub ::std::os::raw::c_uint);
+pub use self::CUexternalSemaphoreHandleType_enum as CUexternalSemaphoreHandleType;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC_st {
+ pub type_: CUexternalSemaphoreHandleType,
+ pub handle: CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC_st__bindgen_ty_1,
+ pub flags: ::std::os::raw::c_uint,
+ pub reserved: [::std::os::raw::c_uint; 16usize],
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC_st__bindgen_ty_1 {
+ pub fd: ::std::os::raw::c_int,
+ pub win32: CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC_st__bindgen_ty_1__bindgen_ty_1,
+ pub nvSciSyncObj: *const ::std::os::raw::c_void,
+ _bindgen_union_align: [u64; 2usize],
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC_st__bindgen_ty_1__bindgen_ty_1 {
+ pub handle: *mut ::std::os::raw::c_void,
+ pub name: *const ::std::os::raw::c_void,
+}
+pub type CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC = CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS_st {
+ pub params: CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS_st__bindgen_ty_1,
+ pub flags: ::std::os::raw::c_uint,
+ pub reserved: [::std::os::raw::c_uint; 16usize],
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS_st__bindgen_ty_1 {
+ pub fence: CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS_st__bindgen_ty_1__bindgen_ty_1,
+ pub nvSciSync: CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS_st__bindgen_ty_1__bindgen_ty_2,
+ pub keyedMutex: CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS_st__bindgen_ty_1__bindgen_ty_3,
+ pub reserved: [::std::os::raw::c_uint; 12usize],
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS_st__bindgen_ty_1__bindgen_ty_1 {
+ pub value: ::std::os::raw::c_ulonglong,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS_st__bindgen_ty_1__bindgen_ty_2 {
+ pub fence: *mut ::std::os::raw::c_void,
+ pub reserved: ::std::os::raw::c_ulonglong,
+ _bindgen_union_align: u64,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS_st__bindgen_ty_1__bindgen_ty_3 {
+ pub key: ::std::os::raw::c_ulonglong,
+}
+pub type CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS = CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS_st {
+ pub params: CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS_st__bindgen_ty_1,
+ pub flags: ::std::os::raw::c_uint,
+ pub reserved: [::std::os::raw::c_uint; 16usize],
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS_st__bindgen_ty_1 {
+ pub fence: CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS_st__bindgen_ty_1__bindgen_ty_1,
+ pub nvSciSync: CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS_st__bindgen_ty_1__bindgen_ty_2,
+ pub keyedMutex: CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS_st__bindgen_ty_1__bindgen_ty_3,
+ pub reserved: [::std::os::raw::c_uint; 10usize],
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS_st__bindgen_ty_1__bindgen_ty_1 {
+ pub value: ::std::os::raw::c_ulonglong,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS_st__bindgen_ty_1__bindgen_ty_2 {
+ pub fence: *mut ::std::os::raw::c_void,
+ pub reserved: ::std::os::raw::c_ulonglong,
+ _bindgen_union_align: u64,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS_st__bindgen_ty_1__bindgen_ty_3 {
+ pub key: ::std::os::raw::c_ulonglong,
+ pub timeoutMs: ::std::os::raw::c_uint,
+}
+pub type CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS = CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS_st;
+pub type CUmemGenericAllocationHandle = ::std::os::raw::c_ulonglong;
+impl CUmemAllocationHandleType_enum {
+ pub const CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR: CUmemAllocationHandleType_enum =
+ CUmemAllocationHandleType_enum(1);
+}
+impl CUmemAllocationHandleType_enum {
+ pub const CU_MEM_HANDLE_TYPE_WIN32: CUmemAllocationHandleType_enum =
+ CUmemAllocationHandleType_enum(2);
+}
+impl CUmemAllocationHandleType_enum {
+ pub const CU_MEM_HANDLE_TYPE_WIN32_KMT: CUmemAllocationHandleType_enum =
+ CUmemAllocationHandleType_enum(4);
+}
+impl CUmemAllocationHandleType_enum {
+ pub const CU_MEM_HANDLE_TYPE_MAX: CUmemAllocationHandleType_enum =
+ CUmemAllocationHandleType_enum(4294967295);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUmemAllocationHandleType_enum(pub ::std::os::raw::c_uint);
+pub use self::CUmemAllocationHandleType_enum as CUmemAllocationHandleType;
+impl CUmemAccess_flags_enum {
+ pub const CU_MEM_ACCESS_FLAGS_PROT_NONE: CUmemAccess_flags_enum = CUmemAccess_flags_enum(0);
+}
+impl CUmemAccess_flags_enum {
+ pub const CU_MEM_ACCESS_FLAGS_PROT_READ: CUmemAccess_flags_enum = CUmemAccess_flags_enum(1);
+}
+impl CUmemAccess_flags_enum {
+ pub const CU_MEM_ACCESS_FLAGS_PROT_READWRITE: CUmemAccess_flags_enum =
+ CUmemAccess_flags_enum(3);
+}
+impl CUmemAccess_flags_enum {
+ pub const CU_MEM_ACCESS_FLAGS_PROT_MAX: CUmemAccess_flags_enum =
+ CUmemAccess_flags_enum(4294967295);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUmemAccess_flags_enum(pub ::std::os::raw::c_uint);
+pub use self::CUmemAccess_flags_enum as CUmemAccess_flags;
+impl CUmemLocationType_enum {
+ pub const CU_MEM_LOCATION_TYPE_INVALID: CUmemLocationType_enum = CUmemLocationType_enum(0);
+}
+impl CUmemLocationType_enum {
+ pub const CU_MEM_LOCATION_TYPE_DEVICE: CUmemLocationType_enum = CUmemLocationType_enum(1);
+}
+impl CUmemLocationType_enum {
+ pub const CU_MEM_LOCATION_TYPE_MAX: CUmemLocationType_enum = CUmemLocationType_enum(4294967295);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUmemLocationType_enum(pub ::std::os::raw::c_uint);
+pub use self::CUmemLocationType_enum as CUmemLocationType;
+impl CUmemAllocationType_enum {
+ pub const CU_MEM_ALLOCATION_TYPE_INVALID: CUmemAllocationType_enum =
+ CUmemAllocationType_enum(0);
+}
+impl CUmemAllocationType_enum {
+ pub const CU_MEM_ALLOCATION_TYPE_PINNED: CUmemAllocationType_enum = CUmemAllocationType_enum(1);
+}
+impl CUmemAllocationType_enum {
+ pub const CU_MEM_ALLOCATION_TYPE_MAX: CUmemAllocationType_enum =
+ CUmemAllocationType_enum(4294967295);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUmemAllocationType_enum(pub ::std::os::raw::c_uint);
+pub use self::CUmemAllocationType_enum as CUmemAllocationType;
+impl CUmemAllocationGranularity_flags_enum {
+ pub const CU_MEM_ALLOC_GRANULARITY_MINIMUM: CUmemAllocationGranularity_flags_enum =
+ CUmemAllocationGranularity_flags_enum(0);
+}
+impl CUmemAllocationGranularity_flags_enum {
+ pub const CU_MEM_ALLOC_GRANULARITY_RECOMMENDED: CUmemAllocationGranularity_flags_enum =
+ CUmemAllocationGranularity_flags_enum(1);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUmemAllocationGranularity_flags_enum(pub ::std::os::raw::c_uint);
+pub use self::CUmemAllocationGranularity_flags_enum as CUmemAllocationGranularity_flags;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUmemLocation_st {
+ pub type_: CUmemLocationType,
+ pub id: ::std::os::raw::c_int,
+}
+pub type CUmemLocation = CUmemLocation_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUmemAllocationProp_st {
+ pub type_: CUmemAllocationType,
+ pub requestedHandleTypes: CUmemAllocationHandleType,
+ pub location: CUmemLocation,
+ pub win32HandleMetaData: *mut ::std::os::raw::c_void,
+ pub allocFlags: CUmemAllocationProp_st__bindgen_ty_1,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUmemAllocationProp_st__bindgen_ty_1 {
+ pub compressionType: ::std::os::raw::c_uchar,
+ pub gpuDirectRDMACapable: ::std::os::raw::c_uchar,
+ pub reserved: [::std::os::raw::c_uchar; 6usize],
+}
+pub type CUmemAllocationProp = CUmemAllocationProp_st;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct CUmemAccessDesc_st {
+ pub location: CUmemLocation,
+ pub flags: CUmemAccess_flags,
+}
+pub type CUmemAccessDesc = CUmemAccessDesc_st;
+impl CUgraphExecUpdateResult_enum {
+ pub const CU_GRAPH_EXEC_UPDATE_SUCCESS: CUgraphExecUpdateResult_enum =
+ CUgraphExecUpdateResult_enum(0);
+}
+impl CUgraphExecUpdateResult_enum {
+ pub const CU_GRAPH_EXEC_UPDATE_ERROR: CUgraphExecUpdateResult_enum =
+ CUgraphExecUpdateResult_enum(1);
+}
+impl CUgraphExecUpdateResult_enum {
+ pub const CU_GRAPH_EXEC_UPDATE_ERROR_TOPOLOGY_CHANGED: CUgraphExecUpdateResult_enum =
+ CUgraphExecUpdateResult_enum(2);
+}
+impl CUgraphExecUpdateResult_enum {
+ pub const CU_GRAPH_EXEC_UPDATE_ERROR_NODE_TYPE_CHANGED: CUgraphExecUpdateResult_enum =
+ CUgraphExecUpdateResult_enum(3);
+}
+impl CUgraphExecUpdateResult_enum {
+ pub const CU_GRAPH_EXEC_UPDATE_ERROR_FUNCTION_CHANGED: CUgraphExecUpdateResult_enum =
+ CUgraphExecUpdateResult_enum(4);
+}
+impl CUgraphExecUpdateResult_enum {
+ pub const CU_GRAPH_EXEC_UPDATE_ERROR_PARAMETERS_CHANGED: CUgraphExecUpdateResult_enum =
+ CUgraphExecUpdateResult_enum(5);
+}
+impl CUgraphExecUpdateResult_enum {
+ pub const CU_GRAPH_EXEC_UPDATE_ERROR_NOT_SUPPORTED: CUgraphExecUpdateResult_enum =
+ CUgraphExecUpdateResult_enum(6);
+}
+#[repr(transparent)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CUgraphExecUpdateResult_enum(pub ::std::os::raw::c_uint);
+pub use self::CUgraphExecUpdateResult_enum as CUgraphExecUpdateResult;
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGetErrorString(
+ error: CUresult,
+ pStr: *mut *const ::std::os::raw::c_char,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGetErrorName(
+ error: CUresult,
+ pStr: *mut *const ::std::os::raw::c_char,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuInit(Flags: ::std::os::raw::c_uint) -> CUresult {
+ r#impl::init().encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDriverGetVersion(driverVersion: *mut ::std::os::raw::c_int) -> CUresult {
+ unsafe { *driverVersion = r#impl::driver_get_version() };
+ CUresult::CUDA_SUCCESS
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDeviceGet(device: *mut CUdevice, ordinal: ::std::os::raw::c_int) -> CUresult {
+ r#impl::device::get(device.decuda(), ordinal).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDeviceGetCount(count: *mut ::std::os::raw::c_int) -> CUresult {
+ r#impl::device::get_count(count).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDeviceGetName(
+ name: *mut ::std::os::raw::c_char,
+ len: ::std::os::raw::c_int,
+ dev: CUdevice,
+) -> CUresult {
+ r#impl::device::get_name(name, len, dev.decuda()).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDeviceGetUuid(uuid: *mut CUuuid, dev: CUdevice) -> CUresult {
+ r#impl::device::get_uuid(uuid, dev.decuda()).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDeviceTotalMem_v2(bytes: *mut usize, dev: CUdevice) -> CUresult {
+ r#impl::device::total_mem_v2(bytes, dev.decuda()).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDeviceGetAttribute(
+ pi: *mut ::std::os::raw::c_int,
+ attrib: CUdevice_attribute,
+ dev: CUdevice,
+) -> CUresult {
+ r#impl::device::get_attribute(pi, attrib, dev.decuda()).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDeviceGetNvSciSyncAttributes(
+ nvSciSyncAttrList: *mut ::std::os::raw::c_void,
+ dev: CUdevice,
+ flags: ::std::os::raw::c_int,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDeviceGetProperties(prop: *mut CUdevprop, dev: CUdevice) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDeviceComputeCapability(
+ major: *mut ::std::os::raw::c_int,
+ minor: *mut ::std::os::raw::c_int,
+ dev: CUdevice,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDevicePrimaryCtxRetain(pctx: *mut CUcontext, dev: CUdevice) -> CUresult {
+ r#impl::device::primary_ctx_retain(pctx.decuda(), dev.decuda()).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDevicePrimaryCtxRelease(dev: CUdevice) -> CUresult {
+ cuDevicePrimaryCtxRelease_v2(dev)
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDevicePrimaryCtxRelease_v2(dev: CUdevice) -> CUresult {
+ r#impl::device::primary_ctx_release_v2(dev.decuda())
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDevicePrimaryCtxSetFlags(
+ dev: CUdevice,
+ flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ cuDevicePrimaryCtxSetFlags_v2(dev, flags)
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDevicePrimaryCtxSetFlags_v2(
+ dev: CUdevice,
+ flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDevicePrimaryCtxGetState(
+ dev: CUdevice,
+ flags: *mut ::std::os::raw::c_uint,
+ active: *mut ::std::os::raw::c_int,
+) -> CUresult {
+ r#impl::device::primary_ctx_get_state(dev.decuda(), flags, active).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDevicePrimaryCtxReset(dev: CUdevice) -> CUresult {
+ cuDevicePrimaryCtxReset_v2(dev)
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDevicePrimaryCtxReset_v2(dev: CUdevice) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxCreate_v2(
+ pctx: *mut CUcontext,
+ flags: ::std::os::raw::c_uint,
+ dev: CUdevice,
+) -> CUresult {
+ r#impl::context::create_v2(pctx.decuda(), flags, dev.decuda()).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxDestroy_v2(ctx: CUcontext) -> CUresult {
+ r#impl::context::destroy_v2(ctx.decuda()).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxPushCurrent_v2(ctx: CUcontext) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxPopCurrent_v2(pctx: *mut CUcontext) -> CUresult {
+ r#impl::context::pop_current_v2(pctx.decuda())
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxSetCurrent(ctx: CUcontext) -> CUresult {
+ r#impl::context::set_current(ctx.decuda())
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxGetCurrent(pctx: *mut CUcontext) -> CUresult {
+ r#impl::context::get_current(pctx.decuda()).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxGetDevice(device: *mut CUdevice) -> CUresult {
+ r#impl::context::get_device(device.decuda()).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxGetFlags(flags: *mut ::std::os::raw::c_uint) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxSynchronize() -> CUresult {
+ r#impl::context::synchronize()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxSetLimit(limit: CUlimit, value: usize) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxGetLimit(pvalue: *mut usize, limit: CUlimit) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxGetCacheConfig(pconfig: *mut CUfunc_cache) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxSetCacheConfig(config: CUfunc_cache) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxGetSharedMemConfig(pConfig: *mut CUsharedconfig) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxSetSharedMemConfig(config: CUsharedconfig) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxGetApiVersion(
+ ctx: CUcontext,
+ version: *mut ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::context::get_api_version(ctx.decuda(), version).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxGetStreamPriorityRange(
+ leastPriority: *mut ::std::os::raw::c_int,
+ greatestPriority: *mut ::std::os::raw::c_int,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxResetPersistingL2Cache() -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxAttach(pctx: *mut CUcontext, flags: ::std::os::raw::c_uint) -> CUresult {
+ r#impl::context::attach(pctx.decuda(), flags).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxDetach(ctx: CUcontext) -> CUresult {
+ r#impl::context::detach(ctx.decuda()).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuModuleLoad(
+ module: *mut CUmodule,
+ fname: *const ::std::os::raw::c_char,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuModuleLoadData(
+ module: *mut CUmodule,
+ image: *const ::std::os::raw::c_void,
+) -> CUresult {
+ r#impl::module::load_data(module.decuda(), image).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuModuleLoadDataEx(
+ module: *mut CUmodule,
+ image: *const ::std::os::raw::c_void,
+ numOptions: ::std::os::raw::c_uint,
+ options: *mut CUjit_option,
+ optionValues: *mut *mut ::std::os::raw::c_void,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuModuleLoadFatBinary(
+ module: *mut CUmodule,
+ fatCubin: *const ::std::os::raw::c_void,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuModuleUnload(hmod: CUmodule) -> CUresult {
+ r#impl::module::unload(hmod.decuda()).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuModuleGetFunction(
+ hfunc: *mut CUfunction,
+ hmod: CUmodule,
+ name: *const ::std::os::raw::c_char,
+) -> CUresult {
+ r#impl::module::get_function(hfunc.decuda(), hmod.decuda(), name).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuModuleGetGlobal_v2(
+ dptr: *mut CUdeviceptr,
+ bytes: *mut usize,
+ hmod: CUmodule,
+ name: *const ::std::os::raw::c_char,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuModuleGetTexRef(
+ pTexRef: *mut CUtexref,
+ hmod: CUmodule,
+ name: *const ::std::os::raw::c_char,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuModuleGetSurfRef(
+ pSurfRef: *mut CUsurfref,
+ hmod: CUmodule,
+ name: *const ::std::os::raw::c_char,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuLinkCreate_v2(
+ numOptions: ::std::os::raw::c_uint,
+ options: *mut CUjit_option,
+ optionValues: *mut *mut ::std::os::raw::c_void,
+ stateOut: *mut CUlinkState,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuLinkAddData_v2(
+ state: CUlinkState,
+ type_: CUjitInputType,
+ data: *mut ::std::os::raw::c_void,
+ size: usize,
+ name: *const ::std::os::raw::c_char,
+ numOptions: ::std::os::raw::c_uint,
+ options: *mut CUjit_option,
+ optionValues: *mut *mut ::std::os::raw::c_void,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuLinkAddFile_v2(
+ state: CUlinkState,
+ type_: CUjitInputType,
+ path: *const ::std::os::raw::c_char,
+ numOptions: ::std::os::raw::c_uint,
+ options: *mut CUjit_option,
+ optionValues: *mut *mut ::std::os::raw::c_void,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuLinkComplete(
+ state: CUlinkState,
+ cubinOut: *mut *mut ::std::os::raw::c_void,
+ sizeOut: *mut usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuLinkDestroy(state: CUlinkState) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemGetInfo_v2(free: *mut usize, total: *mut usize) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemAlloc_v2(dptr: *mut CUdeviceptr, bytesize: usize) -> CUresult {
+ r#impl::memory::alloc_v2(dptr.decuda(), bytesize).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemAllocPitch_v2(
+ dptr: *mut CUdeviceptr,
+ pPitch: *mut usize,
+ WidthInBytes: usize,
+ Height: usize,
+ ElementSizeBytes: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemFree_v2(dptr: CUdeviceptr) -> CUresult {
+ r#impl::memory::free_v2(dptr.decuda()).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemGetAddressRange_v2(
+ pbase: *mut CUdeviceptr,
+ psize: *mut usize,
+ dptr: CUdeviceptr,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemAllocHost_v2(
+ pp: *mut *mut ::std::os::raw::c_void,
+ bytesize: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemFreeHost(p: *mut ::std::os::raw::c_void) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemHostAlloc(
+ pp: *mut *mut ::std::os::raw::c_void,
+ bytesize: usize,
+ Flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemHostGetDevicePointer_v2(
+ pdptr: *mut CUdeviceptr,
+ p: *mut ::std::os::raw::c_void,
+ Flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemHostGetFlags(
+ pFlags: *mut ::std::os::raw::c_uint,
+ p: *mut ::std::os::raw::c_void,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemAllocManaged(
+ dptr: *mut CUdeviceptr,
+ bytesize: usize,
+ flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDeviceGetByPCIBusId(
+ dev: *mut CUdevice,
+ pciBusId: *const ::std::os::raw::c_char,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDeviceGetPCIBusId(
+ pciBusId: *mut ::std::os::raw::c_char,
+ len: ::std::os::raw::c_int,
+ dev: CUdevice,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuIpcGetEventHandle(pHandle: *mut CUipcEventHandle, event: CUevent) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuIpcOpenEventHandle(
+ phEvent: *mut CUevent,
+ handle: CUipcEventHandle,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuIpcGetMemHandle(pHandle: *mut CUipcMemHandle, dptr: CUdeviceptr) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuIpcOpenMemHandle(
+ pdptr: *mut CUdeviceptr,
+ handle: CUipcMemHandle,
+ Flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuIpcCloseMemHandle(dptr: CUdeviceptr) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemHostRegister_v2(
+ p: *mut ::std::os::raw::c_void,
+ bytesize: usize,
+ Flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemHostUnregister(p: *mut ::std::os::raw::c_void) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpy(dst: CUdeviceptr, src: CUdeviceptr, ByteCount: usize) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpyPeer(
+ dstDevice: CUdeviceptr,
+ dstContext: CUcontext,
+ srcDevice: CUdeviceptr,
+ srcContext: CUcontext,
+ ByteCount: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpyHtoD_v2(
+ dstDevice: CUdeviceptr,
+ srcHost: *const ::std::os::raw::c_void,
+ ByteCount: usize,
+) -> CUresult {
+ r#impl::memory::copy_v2(dstDevice.decuda(), srcHost, ByteCount).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpyDtoH_v2(
+ dstHost: *mut ::std::os::raw::c_void,
+ srcDevice: CUdeviceptr,
+ ByteCount: usize,
+) -> CUresult {
+ r#impl::memory::copy_v2(dstHost, srcDevice.decuda(), ByteCount).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpyDtoD_v2(
+ dstDevice: CUdeviceptr,
+ srcDevice: CUdeviceptr,
+ ByteCount: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpyDtoA_v2(
+ dstArray: CUarray,
+ dstOffset: usize,
+ srcDevice: CUdeviceptr,
+ ByteCount: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpyAtoD_v2(
+ dstDevice: CUdeviceptr,
+ srcArray: CUarray,
+ srcOffset: usize,
+ ByteCount: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpyHtoA_v2(
+ dstArray: CUarray,
+ dstOffset: usize,
+ srcHost: *const ::std::os::raw::c_void,
+ ByteCount: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpyAtoH_v2(
+ dstHost: *mut ::std::os::raw::c_void,
+ srcArray: CUarray,
+ srcOffset: usize,
+ ByteCount: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpyAtoA_v2(
+ dstArray: CUarray,
+ dstOffset: usize,
+ srcArray: CUarray,
+ srcOffset: usize,
+ ByteCount: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpy2D_v2(pCopy: *const CUDA_MEMCPY2D) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpy2DUnaligned_v2(pCopy: *const CUDA_MEMCPY2D) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpy3D_v2(pCopy: *const CUDA_MEMCPY3D) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpy3DPeer(pCopy: *const CUDA_MEMCPY3D_PEER) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpyAsync(
+ dst: CUdeviceptr,
+ src: CUdeviceptr,
+ ByteCount: usize,
+ hStream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpyPeerAsync(
+ dstDevice: CUdeviceptr,
+ dstContext: CUcontext,
+ srcDevice: CUdeviceptr,
+ srcContext: CUcontext,
+ ByteCount: usize,
+ hStream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpyHtoDAsync_v2(
+ dstDevice: CUdeviceptr,
+ srcHost: *const ::std::os::raw::c_void,
+ ByteCount: usize,
+ hStream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpyDtoHAsync_v2(
+ dstHost: *mut ::std::os::raw::c_void,
+ srcDevice: CUdeviceptr,
+ ByteCount: usize,
+ hStream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpyDtoDAsync_v2(
+ dstDevice: CUdeviceptr,
+ srcDevice: CUdeviceptr,
+ ByteCount: usize,
+ hStream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpyHtoAAsync_v2(
+ dstArray: CUarray,
+ dstOffset: usize,
+ srcHost: *const ::std::os::raw::c_void,
+ ByteCount: usize,
+ hStream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpyAtoHAsync_v2(
+ dstHost: *mut ::std::os::raw::c_void,
+ srcArray: CUarray,
+ srcOffset: usize,
+ ByteCount: usize,
+ hStream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpy2DAsync_v2(pCopy: *const CUDA_MEMCPY2D, hStream: CUstream) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpy3DAsync_v2(pCopy: *const CUDA_MEMCPY3D, hStream: CUstream) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemcpy3DPeerAsync(
+ pCopy: *const CUDA_MEMCPY3D_PEER,
+ hStream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemsetD8_v2(
+ dstDevice: CUdeviceptr,
+ uc: ::std::os::raw::c_uchar,
+ N: usize,
+) -> CUresult {
+ r#impl::memory::set_d8_v2(dstDevice.decuda(), uc, N).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemsetD16_v2(
+ dstDevice: CUdeviceptr,
+ us: ::std::os::raw::c_ushort,
+ N: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemsetD32_v2(
+ dstDevice: CUdeviceptr,
+ ui: ::std::os::raw::c_uint,
+ N: usize,
+) -> CUresult {
+ r#impl::memory::set_d32_v2(dstDevice.decuda(), ui, N).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemsetD2D8_v2(
+ dstDevice: CUdeviceptr,
+ dstPitch: usize,
+ uc: ::std::os::raw::c_uchar,
+ Width: usize,
+ Height: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemsetD2D16_v2(
+ dstDevice: CUdeviceptr,
+ dstPitch: usize,
+ us: ::std::os::raw::c_ushort,
+ Width: usize,
+ Height: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemsetD2D32_v2(
+ dstDevice: CUdeviceptr,
+ dstPitch: usize,
+ ui: ::std::os::raw::c_uint,
+ Width: usize,
+ Height: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemsetD8Async(
+ dstDevice: CUdeviceptr,
+ uc: ::std::os::raw::c_uchar,
+ N: usize,
+ hStream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemsetD16Async(
+ dstDevice: CUdeviceptr,
+ us: ::std::os::raw::c_ushort,
+ N: usize,
+ hStream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemsetD32Async(
+ dstDevice: CUdeviceptr,
+ ui: ::std::os::raw::c_uint,
+ N: usize,
+ hStream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemsetD2D8Async(
+ dstDevice: CUdeviceptr,
+ dstPitch: usize,
+ uc: ::std::os::raw::c_uchar,
+ Width: usize,
+ Height: usize,
+ hStream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemsetD2D16Async(
+ dstDevice: CUdeviceptr,
+ dstPitch: usize,
+ us: ::std::os::raw::c_ushort,
+ Width: usize,
+ Height: usize,
+ hStream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemsetD2D32Async(
+ dstDevice: CUdeviceptr,
+ dstPitch: usize,
+ ui: ::std::os::raw::c_uint,
+ Width: usize,
+ Height: usize,
+ hStream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuArrayCreate_v2(
+ pHandle: *mut CUarray,
+ pAllocateArray: *const CUDA_ARRAY_DESCRIPTOR,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuArrayGetDescriptor_v2(
+ pArrayDescriptor: *mut CUDA_ARRAY_DESCRIPTOR,
+ hArray: CUarray,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuArrayDestroy(hArray: CUarray) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuArray3DCreate_v2(
+ pHandle: *mut CUarray,
+ pAllocateArray: *const CUDA_ARRAY3D_DESCRIPTOR,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuArray3DGetDescriptor_v2(
+ pArrayDescriptor: *mut CUDA_ARRAY3D_DESCRIPTOR,
+ hArray: CUarray,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMipmappedArrayCreate(
+ pHandle: *mut CUmipmappedArray,
+ pMipmappedArrayDesc: *const CUDA_ARRAY3D_DESCRIPTOR,
+ numMipmapLevels: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMipmappedArrayGetLevel(
+ pLevelArray: *mut CUarray,
+ hMipmappedArray: CUmipmappedArray,
+ level: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMipmappedArrayDestroy(hMipmappedArray: CUmipmappedArray) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemAddressReserve(
+ ptr: *mut CUdeviceptr,
+ size: usize,
+ alignment: usize,
+ addr: CUdeviceptr,
+ flags: ::std::os::raw::c_ulonglong,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemAddressFree(ptr: CUdeviceptr, size: usize) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemCreate(
+ handle: *mut CUmemGenericAllocationHandle,
+ size: usize,
+ prop: *const CUmemAllocationProp,
+ flags: ::std::os::raw::c_ulonglong,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemRelease(handle: CUmemGenericAllocationHandle) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemMap(
+ ptr: CUdeviceptr,
+ size: usize,
+ offset: usize,
+ handle: CUmemGenericAllocationHandle,
+ flags: ::std::os::raw::c_ulonglong,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemUnmap(ptr: CUdeviceptr, size: usize) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemSetAccess(
+ ptr: CUdeviceptr,
+ size: usize,
+ desc: *const CUmemAccessDesc,
+ count: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemGetAccess(
+ flags: *mut ::std::os::raw::c_ulonglong,
+ location: *const CUmemLocation,
+ ptr: CUdeviceptr,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemExportToShareableHandle(
+ shareableHandle: *mut ::std::os::raw::c_void,
+ handle: CUmemGenericAllocationHandle,
+ handleType: CUmemAllocationHandleType,
+ flags: ::std::os::raw::c_ulonglong,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemImportFromShareableHandle(
+ handle: *mut CUmemGenericAllocationHandle,
+ osHandle: *mut ::std::os::raw::c_void,
+ shHandleType: CUmemAllocationHandleType,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemGetAllocationGranularity(
+ granularity: *mut usize,
+ prop: *const CUmemAllocationProp,
+ option: CUmemAllocationGranularity_flags,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemGetAllocationPropertiesFromHandle(
+ prop: *mut CUmemAllocationProp,
+ handle: CUmemGenericAllocationHandle,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemRetainAllocationHandle(
+ handle: *mut CUmemGenericAllocationHandle,
+ addr: *mut ::std::os::raw::c_void,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuPointerGetAttribute(
+ data: *mut ::std::os::raw::c_void,
+ attribute: CUpointer_attribute,
+ ptr: CUdeviceptr,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemPrefetchAsync(
+ devPtr: CUdeviceptr,
+ count: usize,
+ dstDevice: CUdevice,
+ hStream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemAdvise(
+ devPtr: CUdeviceptr,
+ count: usize,
+ advice: CUmem_advise,
+ device: CUdevice,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemRangeGetAttribute(
+ data: *mut ::std::os::raw::c_void,
+ dataSize: usize,
+ attribute: CUmem_range_attribute,
+ devPtr: CUdeviceptr,
+ count: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuMemRangeGetAttributes(
+ data: *mut *mut ::std::os::raw::c_void,
+ dataSizes: *mut usize,
+ attributes: *mut CUmem_range_attribute,
+ numAttributes: usize,
+ devPtr: CUdeviceptr,
+ count: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuPointerSetAttribute(
+ value: *const ::std::os::raw::c_void,
+ attribute: CUpointer_attribute,
+ ptr: CUdeviceptr,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuPointerGetAttributes(
+ numAttributes: ::std::os::raw::c_uint,
+ attributes: *mut CUpointer_attribute,
+ data: *mut *mut ::std::os::raw::c_void,
+ ptr: CUdeviceptr,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamCreate(
+ phStream: *mut CUstream,
+ Flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::stream::create(phStream.decuda(), Flags).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamCreateWithPriority(
+ phStream: *mut CUstream,
+ flags: ::std::os::raw::c_uint,
+ priority: ::std::os::raw::c_int,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamGetPriority(
+ hStream: CUstream,
+ priority: *mut ::std::os::raw::c_int,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamGetFlags(
+ hStream: CUstream,
+ flags: *mut ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamGetCtx(hStream: CUstream, pctx: *mut CUcontext) -> CUresult {
+ r#impl::stream::get_ctx(hStream.decuda(), pctx.decuda()).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamWaitEvent(
+ hStream: CUstream,
+ hEvent: CUevent,
+ Flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamAddCallback(
+ hStream: CUstream,
+ callback: CUstreamCallback,
+ userData: *mut ::std::os::raw::c_void,
+ flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamBeginCapture_v2(
+ hStream: CUstream,
+ mode: CUstreamCaptureMode,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuThreadExchangeStreamCaptureMode(mode: *mut CUstreamCaptureMode) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamEndCapture(hStream: CUstream, phGraph: *mut CUgraph) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamIsCapturing(
+ hStream: CUstream,
+ captureStatus: *mut CUstreamCaptureStatus,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamGetCaptureInfo(
+ hStream: CUstream,
+ captureStatus: *mut CUstreamCaptureStatus,
+ id: *mut cuuint64_t,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamAttachMemAsync(
+ hStream: CUstream,
+ dptr: CUdeviceptr,
+ length: usize,
+ flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamQuery(hStream: CUstream) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamSynchronize(hStream: CUstream) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamDestroy_v2(hStream: CUstream) -> CUresult {
+ r#impl::stream::destroy_v2(hStream.decuda()).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamCopyAttributes(dst: CUstream, src: CUstream) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamGetAttribute(
+ hStream: CUstream,
+ attr: CUstreamAttrID,
+ value_out: *mut CUstreamAttrValue,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamSetAttribute(
+ hStream: CUstream,
+ attr: CUstreamAttrID,
+ value: *const CUstreamAttrValue,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuEventCreate(phEvent: *mut CUevent, Flags: ::std::os::raw::c_uint) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuEventRecord(hEvent: CUevent, hStream: CUstream) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuEventQuery(hEvent: CUevent) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuEventSynchronize(hEvent: CUevent) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuEventDestroy_v2(hEvent: CUevent) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuEventElapsedTime(
+ pMilliseconds: *mut f32,
+ hStart: CUevent,
+ hEnd: CUevent,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuImportExternalMemory(
+ extMem_out: *mut CUexternalMemory,
+ memHandleDesc: *const CUDA_EXTERNAL_MEMORY_HANDLE_DESC,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuExternalMemoryGetMappedBuffer(
+ devPtr: *mut CUdeviceptr,
+ extMem: CUexternalMemory,
+ bufferDesc: *const CUDA_EXTERNAL_MEMORY_BUFFER_DESC,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuExternalMemoryGetMappedMipmappedArray(
+ mipmap: *mut CUmipmappedArray,
+ extMem: CUexternalMemory,
+ mipmapDesc: *const CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDestroyExternalMemory(extMem: CUexternalMemory) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuImportExternalSemaphore(
+ extSem_out: *mut CUexternalSemaphore,
+ semHandleDesc: *const CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuSignalExternalSemaphoresAsync(
+ extSemArray: *const CUexternalSemaphore,
+ paramsArray: *const CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS,
+ numExtSems: ::std::os::raw::c_uint,
+ stream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuWaitExternalSemaphoresAsync(
+ extSemArray: *const CUexternalSemaphore,
+ paramsArray: *const CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS,
+ numExtSems: ::std::os::raw::c_uint,
+ stream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDestroyExternalSemaphore(extSem: CUexternalSemaphore) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamWaitValue32(
+ stream: CUstream,
+ addr: CUdeviceptr,
+ value: cuuint32_t,
+ flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamWaitValue64(
+ stream: CUstream,
+ addr: CUdeviceptr,
+ value: cuuint64_t,
+ flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamWriteValue32(
+ stream: CUstream,
+ addr: CUdeviceptr,
+ value: cuuint32_t,
+ flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamWriteValue64(
+ stream: CUstream,
+ addr: CUdeviceptr,
+ value: cuuint64_t,
+ flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuStreamBatchMemOp(
+ stream: CUstream,
+ count: ::std::os::raw::c_uint,
+ paramArray: *mut CUstreamBatchMemOpParams,
+ flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuFuncGetAttribute(
+ pi: *mut ::std::os::raw::c_int,
+ attrib: CUfunction_attribute,
+ hfunc: CUfunction,
+) -> CUresult {
+ r#impl::function::get_attribute(pi, attrib, hfunc.decuda()).encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuFuncSetAttribute(
+ hfunc: CUfunction,
+ attrib: CUfunction_attribute,
+ value: ::std::os::raw::c_int,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuFuncSetCacheConfig(hfunc: CUfunction, config: CUfunc_cache) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuFuncSetSharedMemConfig(hfunc: CUfunction, config: CUsharedconfig) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuLaunchKernel(
+ f: CUfunction,
+ gridDimX: ::std::os::raw::c_uint,
+ gridDimY: ::std::os::raw::c_uint,
+ gridDimZ: ::std::os::raw::c_uint,
+ blockDimX: ::std::os::raw::c_uint,
+ blockDimY: ::std::os::raw::c_uint,
+ blockDimZ: ::std::os::raw::c_uint,
+ sharedMemBytes: ::std::os::raw::c_uint,
+ hStream: CUstream,
+ kernelParams: *mut *mut ::std::os::raw::c_void,
+ extra: *mut *mut ::std::os::raw::c_void,
+) -> CUresult {
+ r#impl::function::launch_kernel(
+ f.decuda(),
+ gridDimX,
+ gridDimY,
+ gridDimZ,
+ blockDimX,
+ blockDimY,
+ blockDimZ,
+ sharedMemBytes,
+ hStream.decuda(),
+ kernelParams,
+ extra,
+ )
+ .encuda()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuLaunchCooperativeKernel(
+ f: CUfunction,
+ gridDimX: ::std::os::raw::c_uint,
+ gridDimY: ::std::os::raw::c_uint,
+ gridDimZ: ::std::os::raw::c_uint,
+ blockDimX: ::std::os::raw::c_uint,
+ blockDimY: ::std::os::raw::c_uint,
+ blockDimZ: ::std::os::raw::c_uint,
+ sharedMemBytes: ::std::os::raw::c_uint,
+ hStream: CUstream,
+ kernelParams: *mut *mut ::std::os::raw::c_void,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuLaunchCooperativeKernelMultiDevice(
+ launchParamsList: *mut CUDA_LAUNCH_PARAMS,
+ numDevices: ::std::os::raw::c_uint,
+ flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuLaunchHostFunc(
+ hStream: CUstream,
+ fn_: CUhostFn,
+ userData: *mut ::std::os::raw::c_void,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuFuncSetBlockShape(
+ hfunc: CUfunction,
+ x: ::std::os::raw::c_int,
+ y: ::std::os::raw::c_int,
+ z: ::std::os::raw::c_int,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuFuncSetSharedSize(
+ hfunc: CUfunction,
+ bytes: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuParamSetSize(hfunc: CUfunction, numbytes: ::std::os::raw::c_uint) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuParamSeti(
+ hfunc: CUfunction,
+ offset: ::std::os::raw::c_int,
+ value: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuParamSetf(
+ hfunc: CUfunction,
+ offset: ::std::os::raw::c_int,
+ value: f32,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuParamSetv(
+ hfunc: CUfunction,
+ offset: ::std::os::raw::c_int,
+ ptr: *mut ::std::os::raw::c_void,
+ numbytes: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuLaunch(f: CUfunction) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuLaunchGrid(
+ f: CUfunction,
+ grid_width: ::std::os::raw::c_int,
+ grid_height: ::std::os::raw::c_int,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuLaunchGridAsync(
+ f: CUfunction,
+ grid_width: ::std::os::raw::c_int,
+ grid_height: ::std::os::raw::c_int,
+ hStream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuParamSetTexRef(
+ hfunc: CUfunction,
+ texunit: ::std::os::raw::c_int,
+ hTexRef: CUtexref,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphCreate(phGraph: *mut CUgraph, flags: ::std::os::raw::c_uint) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphAddKernelNode(
+ phGraphNode: *mut CUgraphNode,
+ hGraph: CUgraph,
+ dependencies: *const CUgraphNode,
+ numDependencies: usize,
+ nodeParams: *const CUDA_KERNEL_NODE_PARAMS,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphKernelNodeGetParams(
+ hNode: CUgraphNode,
+ nodeParams: *mut CUDA_KERNEL_NODE_PARAMS,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphKernelNodeSetParams(
+ hNode: CUgraphNode,
+ nodeParams: *const CUDA_KERNEL_NODE_PARAMS,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphAddMemcpyNode(
+ phGraphNode: *mut CUgraphNode,
+ hGraph: CUgraph,
+ dependencies: *const CUgraphNode,
+ numDependencies: usize,
+ copyParams: *const CUDA_MEMCPY3D,
+ ctx: CUcontext,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphMemcpyNodeGetParams(
+ hNode: CUgraphNode,
+ nodeParams: *mut CUDA_MEMCPY3D,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphMemcpyNodeSetParams(
+ hNode: CUgraphNode,
+ nodeParams: *const CUDA_MEMCPY3D,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphAddMemsetNode(
+ phGraphNode: *mut CUgraphNode,
+ hGraph: CUgraph,
+ dependencies: *const CUgraphNode,
+ numDependencies: usize,
+ memsetParams: *const CUDA_MEMSET_NODE_PARAMS,
+ ctx: CUcontext,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphMemsetNodeGetParams(
+ hNode: CUgraphNode,
+ nodeParams: *mut CUDA_MEMSET_NODE_PARAMS,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphMemsetNodeSetParams(
+ hNode: CUgraphNode,
+ nodeParams: *const CUDA_MEMSET_NODE_PARAMS,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphAddHostNode(
+ phGraphNode: *mut CUgraphNode,
+ hGraph: CUgraph,
+ dependencies: *const CUgraphNode,
+ numDependencies: usize,
+ nodeParams: *const CUDA_HOST_NODE_PARAMS,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphHostNodeGetParams(
+ hNode: CUgraphNode,
+ nodeParams: *mut CUDA_HOST_NODE_PARAMS,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphHostNodeSetParams(
+ hNode: CUgraphNode,
+ nodeParams: *const CUDA_HOST_NODE_PARAMS,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphAddChildGraphNode(
+ phGraphNode: *mut CUgraphNode,
+ hGraph: CUgraph,
+ dependencies: *const CUgraphNode,
+ numDependencies: usize,
+ childGraph: CUgraph,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphChildGraphNodeGetGraph(
+ hNode: CUgraphNode,
+ phGraph: *mut CUgraph,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphAddEmptyNode(
+ phGraphNode: *mut CUgraphNode,
+ hGraph: CUgraph,
+ dependencies: *const CUgraphNode,
+ numDependencies: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphClone(phGraphClone: *mut CUgraph, originalGraph: CUgraph) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphNodeFindInClone(
+ phNode: *mut CUgraphNode,
+ hOriginalNode: CUgraphNode,
+ hClonedGraph: CUgraph,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphNodeGetType(hNode: CUgraphNode, type_: *mut CUgraphNodeType) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphGetNodes(
+ hGraph: CUgraph,
+ nodes: *mut CUgraphNode,
+ numNodes: *mut usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphGetRootNodes(
+ hGraph: CUgraph,
+ rootNodes: *mut CUgraphNode,
+ numRootNodes: *mut usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphGetEdges(
+ hGraph: CUgraph,
+ from: *mut CUgraphNode,
+ to: *mut CUgraphNode,
+ numEdges: *mut usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphNodeGetDependencies(
+ hNode: CUgraphNode,
+ dependencies: *mut CUgraphNode,
+ numDependencies: *mut usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphNodeGetDependentNodes(
+ hNode: CUgraphNode,
+ dependentNodes: *mut CUgraphNode,
+ numDependentNodes: *mut usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphAddDependencies(
+ hGraph: CUgraph,
+ from: *const CUgraphNode,
+ to: *const CUgraphNode,
+ numDependencies: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphRemoveDependencies(
+ hGraph: CUgraph,
+ from: *const CUgraphNode,
+ to: *const CUgraphNode,
+ numDependencies: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphDestroyNode(hNode: CUgraphNode) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphInstantiate_v2(
+ phGraphExec: *mut CUgraphExec,
+ hGraph: CUgraph,
+ phErrorNode: *mut CUgraphNode,
+ logBuffer: *mut ::std::os::raw::c_char,
+ bufferSize: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphExecKernelNodeSetParams(
+ hGraphExec: CUgraphExec,
+ hNode: CUgraphNode,
+ nodeParams: *const CUDA_KERNEL_NODE_PARAMS,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphExecMemcpyNodeSetParams(
+ hGraphExec: CUgraphExec,
+ hNode: CUgraphNode,
+ copyParams: *const CUDA_MEMCPY3D,
+ ctx: CUcontext,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphExecMemsetNodeSetParams(
+ hGraphExec: CUgraphExec,
+ hNode: CUgraphNode,
+ memsetParams: *const CUDA_MEMSET_NODE_PARAMS,
+ ctx: CUcontext,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphExecHostNodeSetParams(
+ hGraphExec: CUgraphExec,
+ hNode: CUgraphNode,
+ nodeParams: *const CUDA_HOST_NODE_PARAMS,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphLaunch(hGraphExec: CUgraphExec, hStream: CUstream) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphExecDestroy(hGraphExec: CUgraphExec) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphDestroy(hGraph: CUgraph) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphExecUpdate(
+ hGraphExec: CUgraphExec,
+ hGraph: CUgraph,
+ hErrorNode_out: *mut CUgraphNode,
+ updateResult_out: *mut CUgraphExecUpdateResult,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphKernelNodeCopyAttributes(dst: CUgraphNode, src: CUgraphNode) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphKernelNodeGetAttribute(
+ hNode: CUgraphNode,
+ attr: CUkernelNodeAttrID,
+ value_out: *mut CUkernelNodeAttrValue,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphKernelNodeSetAttribute(
+ hNode: CUgraphNode,
+ attr: CUkernelNodeAttrID,
+ value: *const CUkernelNodeAttrValue,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuOccupancyMaxActiveBlocksPerMultiprocessor(
+ numBlocks: *mut ::std::os::raw::c_int,
+ func: CUfunction,
+ blockSize: ::std::os::raw::c_int,
+ dynamicSMemSize: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags(
+ numBlocks: *mut ::std::os::raw::c_int,
+ func: CUfunction,
+ blockSize: ::std::os::raw::c_int,
+ dynamicSMemSize: usize,
+ flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuOccupancyMaxPotentialBlockSize(
+ minGridSize: *mut ::std::os::raw::c_int,
+ blockSize: *mut ::std::os::raw::c_int,
+ func: CUfunction,
+ blockSizeToDynamicSMemSize: CUoccupancyB2DSize,
+ dynamicSMemSize: usize,
+ blockSizeLimit: ::std::os::raw::c_int,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuOccupancyMaxPotentialBlockSizeWithFlags(
+ minGridSize: *mut ::std::os::raw::c_int,
+ blockSize: *mut ::std::os::raw::c_int,
+ func: CUfunction,
+ blockSizeToDynamicSMemSize: CUoccupancyB2DSize,
+ dynamicSMemSize: usize,
+ blockSizeLimit: ::std::os::raw::c_int,
+ flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuOccupancyAvailableDynamicSMemPerBlock(
+ dynamicSmemSize: *mut usize,
+ func: CUfunction,
+ numBlocks: ::std::os::raw::c_int,
+ blockSize: ::std::os::raw::c_int,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefSetArray(
+ hTexRef: CUtexref,
+ hArray: CUarray,
+ Flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefSetMipmappedArray(
+ hTexRef: CUtexref,
+ hMipmappedArray: CUmipmappedArray,
+ Flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefSetAddress_v2(
+ ByteOffset: *mut usize,
+ hTexRef: CUtexref,
+ dptr: CUdeviceptr,
+ bytes: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefSetAddress2D_v3(
+ hTexRef: CUtexref,
+ desc: *const CUDA_ARRAY_DESCRIPTOR,
+ dptr: CUdeviceptr,
+ Pitch: usize,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefSetFormat(
+ hTexRef: CUtexref,
+ fmt: CUarray_format,
+ NumPackedComponents: ::std::os::raw::c_int,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefSetAddressMode(
+ hTexRef: CUtexref,
+ dim: ::std::os::raw::c_int,
+ am: CUaddress_mode,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefSetFilterMode(hTexRef: CUtexref, fm: CUfilter_mode) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefSetMipmapFilterMode(hTexRef: CUtexref, fm: CUfilter_mode) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefSetMipmapLevelBias(hTexRef: CUtexref, bias: f32) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefSetMipmapLevelClamp(
+ hTexRef: CUtexref,
+ minMipmapLevelClamp: f32,
+ maxMipmapLevelClamp: f32,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefSetMaxAnisotropy(
+ hTexRef: CUtexref,
+ maxAniso: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefSetBorderColor(hTexRef: CUtexref, pBorderColor: *mut f32) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefSetFlags(hTexRef: CUtexref, Flags: ::std::os::raw::c_uint) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefGetAddress_v2(pdptr: *mut CUdeviceptr, hTexRef: CUtexref) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefGetArray(phArray: *mut CUarray, hTexRef: CUtexref) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefGetMipmappedArray(
+ phMipmappedArray: *mut CUmipmappedArray,
+ hTexRef: CUtexref,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefGetAddressMode(
+ pam: *mut CUaddress_mode,
+ hTexRef: CUtexref,
+ dim: ::std::os::raw::c_int,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefGetFilterMode(pfm: *mut CUfilter_mode, hTexRef: CUtexref) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefGetFormat(
+ pFormat: *mut CUarray_format,
+ pNumChannels: *mut ::std::os::raw::c_int,
+ hTexRef: CUtexref,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefGetMipmapFilterMode(
+ pfm: *mut CUfilter_mode,
+ hTexRef: CUtexref,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefGetMipmapLevelBias(pbias: *mut f32, hTexRef: CUtexref) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefGetMipmapLevelClamp(
+ pminMipmapLevelClamp: *mut f32,
+ pmaxMipmapLevelClamp: *mut f32,
+ hTexRef: CUtexref,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefGetMaxAnisotropy(
+ pmaxAniso: *mut ::std::os::raw::c_int,
+ hTexRef: CUtexref,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefGetBorderColor(pBorderColor: *mut f32, hTexRef: CUtexref) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefGetFlags(
+ pFlags: *mut ::std::os::raw::c_uint,
+ hTexRef: CUtexref,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefCreate(pTexRef: *mut CUtexref) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexRefDestroy(hTexRef: CUtexref) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuSurfRefSetArray(
+ hSurfRef: CUsurfref,
+ hArray: CUarray,
+ Flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuSurfRefGetArray(phArray: *mut CUarray, hSurfRef: CUsurfref) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexObjectCreate(
+ pTexObject: *mut CUtexObject,
+ pResDesc: *const CUDA_RESOURCE_DESC,
+ pTexDesc: *const CUDA_TEXTURE_DESC,
+ pResViewDesc: *const CUDA_RESOURCE_VIEW_DESC,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexObjectDestroy(texObject: CUtexObject) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexObjectGetResourceDesc(
+ pResDesc: *mut CUDA_RESOURCE_DESC,
+ texObject: CUtexObject,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexObjectGetTextureDesc(
+ pTexDesc: *mut CUDA_TEXTURE_DESC,
+ texObject: CUtexObject,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuTexObjectGetResourceViewDesc(
+ pResViewDesc: *mut CUDA_RESOURCE_VIEW_DESC,
+ texObject: CUtexObject,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuSurfObjectCreate(
+ pSurfObject: *mut CUsurfObject,
+ pResDesc: *const CUDA_RESOURCE_DESC,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuSurfObjectDestroy(surfObject: CUsurfObject) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuSurfObjectGetResourceDesc(
+ pResDesc: *mut CUDA_RESOURCE_DESC,
+ surfObject: CUsurfObject,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDeviceCanAccessPeer(
+ canAccessPeer: *mut ::std::os::raw::c_int,
+ dev: CUdevice,
+ peerDev: CUdevice,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxEnablePeerAccess(
+ peerContext: CUcontext,
+ Flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuCtxDisablePeerAccess(peerContext: CUcontext) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuDeviceGetP2PAttribute(
+ value: *mut ::std::os::raw::c_int,
+ attrib: CUdevice_P2PAttribute,
+ srcDevice: CUdevice,
+ dstDevice: CUdevice,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphicsUnregisterResource(resource: CUgraphicsResource) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphicsSubResourceGetMappedArray(
+ pArray: *mut CUarray,
+ resource: CUgraphicsResource,
+ arrayIndex: ::std::os::raw::c_uint,
+ mipLevel: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphicsResourceGetMappedMipmappedArray(
+ pMipmappedArray: *mut CUmipmappedArray,
+ resource: CUgraphicsResource,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphicsResourceGetMappedPointer_v2(
+ pDevPtr: *mut CUdeviceptr,
+ pSize: *mut usize,
+ resource: CUgraphicsResource,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphicsResourceSetMapFlags_v2(
+ resource: CUgraphicsResource,
+ flags: ::std::os::raw::c_uint,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphicsMapResources(
+ count: ::std::os::raw::c_uint,
+ resources: *mut CUgraphicsResource,
+ hStream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGraphicsUnmapResources(
+ count: ::std::os::raw::c_uint,
+ resources: *mut CUgraphicsResource,
+ hStream: CUstream,
+) -> CUresult {
+ r#impl::unimplemented()
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuGetExportTable(
+ ppExportTable: *mut *const ::std::os::raw::c_void,
+ pExportTableId: *const CUuuid,
+) -> CUresult {
+ r#impl::export_table::get(ppExportTable, pExportTableId)
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "C" fn cuFuncGetModule(hmod: *mut CUmodule, hfunc: CUfunction) -> CUresult {
+ r#impl::unimplemented()
+}
diff --git a/zluda/src/cuda_impl/mod.rs b/zluda/src/cuda_impl/mod.rs
new file mode 100644
index 0000000..63b9049
--- /dev/null
+++ b/zluda/src/cuda_impl/mod.rs
@@ -0,0 +1 @@
+pub mod rt; \ No newline at end of file
diff --git a/zluda/src/cuda_impl/rt.rs b/zluda/src/cuda_impl/rt.rs
new file mode 100644
index 0000000..3931bc3
--- /dev/null
+++ b/zluda/src/cuda_impl/rt.rs
@@ -0,0 +1,2 @@
+pub enum ContextState {}
+pub enum ContextStateManager {}
diff --git a/zluda/src/impl/context.rs b/zluda/src/impl/context.rs
new file mode 100644
index 0000000..873fc47
--- /dev/null
+++ b/zluda/src/impl/context.rs
@@ -0,0 +1,359 @@
+use super::{device, stream::Stream, stream::StreamData, HasLivenessCookie, LiveCheck};
+use super::{CUresult, GlobalState};
+use crate::{cuda::CUcontext, cuda_impl};
+use l0::sys::ze_result_t;
+use std::{cell::RefCell, num::NonZeroU32, os::raw::c_uint, ptr, sync::atomic::AtomicU32};
+use std::{
+ collections::HashSet,
+ mem::{self},
+};
+
+thread_local! {
+ pub static CONTEXT_STACK: RefCell<Vec<*mut Context>> = RefCell::new(Vec::new());
+}
+
+pub type Context = LiveCheck<ContextData>;
+
+impl HasLivenessCookie for ContextData {
+ #[cfg(target_pointer_width = "64")]
+ const COOKIE: usize = 0x5f0119560b643ffb;
+
+ #[cfg(target_pointer_width = "32")]
+ const COOKIE: usize = 0x0b643ffb;
+
+ const LIVENESS_FAIL: CUresult = CUresult::CUDA_ERROR_INVALID_CONTEXT;
+
+ fn try_drop(&mut self) -> Result<(), CUresult> {
+ for stream in self.streams.iter() {
+ let stream = unsafe { &mut **stream };
+ stream.context = ptr::null_mut();
+ Stream::destroy_impl(unsafe { Stream::ptr_from_inner(stream) })?;
+ }
+ Ok(())
+ }
+}
+
+enum ContextRefCount {
+ Primary,
+ NonPrimary(NonZeroU32),
+}
+
+impl ContextRefCount {
+ fn new(is_primary: bool) -> Self {
+ if is_primary {
+ ContextRefCount::Primary
+ } else {
+ ContextRefCount::NonPrimary(unsafe { NonZeroU32::new_unchecked(1) })
+ }
+ }
+
+ fn incr(&mut self) -> Result<(), CUresult> {
+ match self {
+ ContextRefCount::Primary => Ok(()),
+ ContextRefCount::NonPrimary(c) => {
+ let (new_count, overflow) = c.get().overflowing_add(1);
+ if overflow {
+ Err(CUresult::CUDA_ERROR_INVALID_VALUE)
+ } else {
+ *c = unsafe { NonZeroU32::new_unchecked(new_count) };
+ Ok(())
+ }
+ }
+ }
+ }
+
+ #[must_use]
+ fn decr(&mut self) -> bool {
+ match self {
+ ContextRefCount::Primary => false,
+ ContextRefCount::NonPrimary(c) => {
+ if c.get() == 1 {
+ return true;
+ }
+ *c = unsafe { NonZeroU32::new_unchecked(c.get() - 1) };
+ false
+ }
+ }
+ }
+}
+
+pub struct ContextData {
+ pub flags: AtomicU32,
+ // This pointer is null only for a moment when constructing primary context
+ pub device: *mut device::Device,
+ ref_count: ContextRefCount,
+ pub default_stream: StreamData,
+ pub streams: HashSet<*mut StreamData>,
+ // All the fields below are here to support internal CUDA driver API
+ pub cuda_manager: *mut cuda_impl::rt::ContextStateManager,
+ pub cuda_state: *mut cuda_impl::rt::ContextState,
+ pub cuda_dtor_cb: Option<
+ extern "C" fn(
+ CUcontext,
+ *mut cuda_impl::rt::ContextStateManager,
+ *mut cuda_impl::rt::ContextState,
+ ),
+ >,
+}
+
+impl ContextData {
+ pub fn new(
+ l0_ctx: &mut l0::Context,
+ l0_dev: &l0::Device,
+ flags: c_uint,
+ is_primary: bool,
+ dev: *mut device::Device,
+ ) -> Result<Self, CUresult> {
+ let default_stream = StreamData::new_unitialized(l0_ctx, l0_dev)?;
+ Ok(ContextData {
+ flags: AtomicU32::new(flags),
+ device: dev,
+ ref_count: ContextRefCount::new(is_primary),
+ default_stream,
+ streams: HashSet::new(),
+ cuda_manager: ptr::null_mut(),
+ cuda_state: ptr::null_mut(),
+ cuda_dtor_cb: None,
+ })
+ }
+}
+
+impl Context {
+ pub fn late_init(&mut self) {
+ let ctx_data = self.as_option_mut().unwrap();
+ ctx_data.default_stream.context = ctx_data as *mut _;
+ }
+}
+
+pub fn create_v2(
+ pctx: *mut *mut Context,
+ flags: u32,
+ dev_idx: device::Index,
+) -> Result<(), CUresult> {
+ if pctx == ptr::null_mut() {
+ return Err(CUresult::CUDA_ERROR_INVALID_VALUE);
+ }
+ let mut ctx_box = GlobalState::lock_device(dev_idx, |dev| {
+ let dev_ptr = dev as *mut _;
+ let mut ctx_box = Box::new(LiveCheck::new(ContextData::new(
+ &mut dev.l0_context,
+ &dev.base,
+ flags,
+ false,
+ dev_ptr as *mut _,
+ )?));
+ ctx_box.late_init();
+ Ok::<_, CUresult>(ctx_box)
+ })??;
+ let ctx_ref = ctx_box.as_mut() as *mut Context;
+ unsafe { *pctx = ctx_ref };
+ mem::forget(ctx_box);
+ CONTEXT_STACK.with(|stack| stack.borrow_mut().push(ctx_ref));
+ Ok(())
+}
+
+pub fn destroy_v2(ctx: *mut Context) -> Result<(), CUresult> {
+ if ctx == ptr::null_mut() {
+ return Err(CUresult::CUDA_ERROR_INVALID_VALUE);
+ }
+ CONTEXT_STACK.with(|stack| {
+ let mut stack = stack.borrow_mut();
+ let should_pop = match stack.last() {
+ Some(active_ctx) => *active_ctx == (ctx as *mut _),
+ None => false,
+ };
+ if should_pop {
+ stack.pop();
+ }
+ });
+ GlobalState::lock(|_| Context::destroy_impl(ctx))?
+}
+
+pub fn pop_current_v2(pctx: *mut *mut Context) -> CUresult {
+ if pctx == ptr::null_mut() {
+ return CUresult::CUDA_ERROR_INVALID_VALUE;
+ }
+ let mut ctx = CONTEXT_STACK.with(|stack| stack.borrow_mut().pop());
+ let ctx_ptr = match &mut ctx {
+ Some(ctx) => *ctx as *mut _,
+ None => return CUresult::CUDA_ERROR_INVALID_CONTEXT,
+ };
+ unsafe { *pctx = ctx_ptr };
+ CUresult::CUDA_SUCCESS
+}
+
+pub fn get_current(pctx: *mut *mut Context) -> l0::Result<()> {
+ if pctx == ptr::null_mut() {
+ return Err(ze_result_t::ZE_RESULT_ERROR_INVALID_ARGUMENT);
+ }
+ let ctx = CONTEXT_STACK.with(|stack| match stack.borrow().last() {
+ Some(ctx) => *ctx as *mut _,
+ None => ptr::null_mut(),
+ });
+ unsafe { *pctx = ctx };
+ Ok(())
+}
+
+pub fn set_current(ctx: *mut Context) -> CUresult {
+ if ctx == ptr::null_mut() {
+ CONTEXT_STACK.with(|stack| stack.borrow_mut().pop());
+ CUresult::CUDA_SUCCESS
+ } else {
+ CONTEXT_STACK.with(|stack| stack.borrow_mut().push(ctx));
+ CUresult::CUDA_SUCCESS
+ }
+}
+
+pub fn get_api_version(ctx: *mut Context, version: *mut u32) -> Result<(), CUresult> {
+ if ctx == ptr::null_mut() {
+ return Err(CUresult::CUDA_ERROR_INVALID_VALUE);
+ }
+ GlobalState::lock(|_| {
+ unsafe { &*ctx }.as_result()?;
+ Ok::<_, CUresult>(())
+ })??;
+ //TODO: query device for properties roughly matching CUDA API version
+ unsafe { *version = 1100 };
+ Ok(())
+}
+
+pub fn get_device(dev: *mut device::Index) -> Result<(), CUresult> {
+ let dev_idx = GlobalState::lock_current_context(|ctx| unsafe { &*ctx.device }.index)?;
+ unsafe { *dev = dev_idx };
+ Ok(())
+}
+
+pub fn attach(pctx: *mut *mut Context, _flags: c_uint) -> Result<(), CUresult> {
+ if pctx == ptr::null_mut() {
+ return Err(CUresult::CUDA_ERROR_INVALID_VALUE);
+ }
+ let ctx = GlobalState::lock_current_context_unchecked(|unchecked_ctx| {
+ let ctx = unchecked_ctx.as_result_mut()?;
+ ctx.ref_count.incr()?;
+ Ok::<_, CUresult>(unchecked_ctx as *mut _)
+ })??;
+ unsafe { *pctx = ctx };
+ Ok(())
+}
+
+pub fn detach(pctx: *mut Context) -> Result<(), CUresult> {
+ if pctx == ptr::null_mut() {
+ return Err(CUresult::CUDA_ERROR_INVALID_VALUE);
+ }
+ GlobalState::lock_current_context_unchecked(|unchecked_ctx| {
+ let ctx = unchecked_ctx.as_result_mut()?;
+ if ctx.ref_count.decr() {
+ Context::destroy_impl(unchecked_ctx)?;
+ }
+ Ok::<_, CUresult>(())
+ })?
+}
+
+pub(crate) fn synchronize() -> CUresult {
+ // TODO: change the implementation once we do async stream operations
+ CUresult::CUDA_SUCCESS
+}
+
+#[cfg(test)]
+mod test {
+ use super::super::test::CudaDriverFns;
+ use super::super::CUresult;
+ use std::{ffi::c_void, ptr};
+
+ cuda_driver_test!(destroy_leaves_zombie_context);
+
+ fn destroy_leaves_zombie_context<T: CudaDriverFns>() {
+ assert_eq!(T::cuInit(0), CUresult::CUDA_SUCCESS);
+ let mut ctx1 = ptr::null_mut();
+ let mut ctx2 = ptr::null_mut();
+ let mut ctx3 = ptr::null_mut();
+ assert_eq!(T::cuCtxCreate_v2(&mut ctx1, 0, 0), CUresult::CUDA_SUCCESS);
+ assert_eq!(T::cuCtxCreate_v2(&mut ctx2, 0, 0), CUresult::CUDA_SUCCESS);
+ assert_eq!(T::cuCtxCreate_v2(&mut ctx3, 0, 0), CUresult::CUDA_SUCCESS);
+ assert_eq!(T::cuCtxDestroy_v2(ctx2), CUresult::CUDA_SUCCESS);
+ let mut popped_ctx1 = ptr::null_mut();
+ assert_eq!(
+ T::cuCtxPopCurrent_v2(&mut popped_ctx1),
+ CUresult::CUDA_SUCCESS
+ );
+ assert_eq!(popped_ctx1, ctx3);
+ let mut popped_ctx2 = ptr::null_mut();
+ assert_eq!(
+ T::cuCtxPopCurrent_v2(&mut popped_ctx2),
+ CUresult::CUDA_SUCCESS
+ );
+ assert_eq!(popped_ctx2, ctx2);
+ let mut popped_ctx3 = ptr::null_mut();
+ assert_eq!(
+ T::cuCtxPopCurrent_v2(&mut popped_ctx3),
+ CUresult::CUDA_SUCCESS
+ );
+ assert_eq!(popped_ctx3, ctx1);
+ let mut temp = 0;
+ assert_eq!(
+ T::cuCtxGetApiVersion(ctx2, &mut temp),
+ CUresult::CUDA_ERROR_INVALID_CONTEXT
+ );
+ assert_eq!(
+ T::cuCtxPopCurrent_v2(&mut ptr::null_mut()),
+ CUresult::CUDA_ERROR_INVALID_CONTEXT
+ );
+ }
+
+ cuda_driver_test!(empty_pop_fails);
+
+ fn empty_pop_fails<T: CudaDriverFns>() {
+ assert_eq!(T::cuInit(0), CUresult::CUDA_SUCCESS);
+ let mut ctx = ptr::null_mut();
+ assert_eq!(
+ T::cuCtxPopCurrent_v2(&mut ctx),
+ CUresult::CUDA_ERROR_INVALID_CONTEXT
+ );
+ }
+
+ cuda_driver_test!(destroy_pops_top_of_stack);
+
+ fn destroy_pops_top_of_stack<T: CudaDriverFns>() {
+ assert_eq!(T::cuInit(0), CUresult::CUDA_SUCCESS);
+ let mut ctx1 = ptr::null_mut();
+ let mut ctx2 = ptr::null_mut();
+ assert_eq!(T::cuCtxCreate_v2(&mut ctx1, 0, 0), CUresult::CUDA_SUCCESS);
+ assert_eq!(T::cuCtxCreate_v2(&mut ctx2, 0, 0), CUresult::CUDA_SUCCESS);
+ assert_eq!(T::cuCtxDestroy_v2(ctx2), CUresult::CUDA_SUCCESS);
+ let mut popped_ctx1 = ptr::null_mut();
+ assert_eq!(
+ T::cuCtxPopCurrent_v2(&mut popped_ctx1),
+ CUresult::CUDA_SUCCESS
+ );
+ assert_eq!(popped_ctx1, ctx1);
+ let mut popped_ctx2 = ptr::null_mut();
+ assert_eq!(
+ T::cuCtxPopCurrent_v2(&mut popped_ctx2),
+ CUresult::CUDA_ERROR_INVALID_CONTEXT
+ );
+ }
+
+ cuda_driver_test!(double_destroy_fails);
+
+ fn double_destroy_fails<T: CudaDriverFns>() {
+ assert_eq!(T::cuInit(0), CUresult::CUDA_SUCCESS);
+ let mut ctx = ptr::null_mut();
+ assert_eq!(T::cuCtxCreate_v2(&mut ctx, 0, 0), CUresult::CUDA_SUCCESS);
+ assert_eq!(T::cuCtxDestroy_v2(ctx), CUresult::CUDA_SUCCESS);
+ let destroy_result = T::cuCtxDestroy_v2(ctx);
+ // original CUDA impl returns randomly one or the other
+ assert!(
+ destroy_result == CUresult::CUDA_ERROR_INVALID_CONTEXT
+ || destroy_result == CUresult::CUDA_ERROR_CONTEXT_IS_DESTROYED
+ );
+ }
+
+ cuda_driver_test!(no_current_on_init);
+
+ fn no_current_on_init<T: CudaDriverFns>() {
+ assert_eq!(T::cuInit(0), CUresult::CUDA_SUCCESS);
+ let mut ctx = 1 as *mut c_void;
+ assert_eq!(T::cuCtxGetCurrent(&mut ctx), CUresult::CUDA_SUCCESS);
+ assert_eq!(ctx, ptr::null_mut());
+ }
+}
diff --git a/zluda/src/impl/device.rs b/zluda/src/impl/device.rs
new file mode 100644
index 0000000..8fa24a8
--- /dev/null
+++ b/zluda/src/impl/device.rs
@@ -0,0 +1,407 @@
+use super::{context, CUresult, GlobalState};
+use crate::cuda;
+use cuda::{CUdevice_attribute, CUuuid_st};
+use std::{
+ cmp, mem,
+ os::raw::{c_char, c_int},
+ ptr,
+ sync::atomic::{AtomicU32, Ordering},
+};
+
+const PROJECT_URL_SUFFIX_SHORT: &'static str = " [ZLUDA]";
+const PROJECT_URL_SUFFIX_LONG: &'static str = " [github.com/vosen/ZLUDA]";
+
+#[repr(transparent)]
+#[derive(Clone, Copy, Eq, PartialEq, Hash)]
+pub struct Index(pub c_int);
+
+pub struct Device {
+ pub index: Index,
+ pub base: l0::Device,
+ pub default_queue: l0::CommandQueue,
+ pub l0_context: l0::Context,
+ pub primary_context: context::Context,
+ properties: Option<Box<l0::sys::ze_device_properties_t>>,
+ image_properties: Option<Box<l0::sys::ze_device_image_properties_t>>,
+ memory_properties: Option<Vec<l0::sys::ze_device_memory_properties_t>>,
+ compute_properties: Option<Box<l0::sys::ze_device_compute_properties_t>>,
+}
+
+unsafe impl Send for Device {}
+
+impl Device {
+ // Unsafe because it does not fully initalize primary_context
+ unsafe fn new(drv: &l0::Driver, l0_dev: l0::Device, idx: usize) -> Result<Self, CUresult> {
+ let mut ctx = l0::Context::new(drv)?;
+ let queue = l0::CommandQueue::new(&mut ctx, &l0_dev)?;
+ let primary_context = context::Context::new(context::ContextData::new(
+ &mut ctx,
+ &l0_dev,
+ 0,
+ true,
+ ptr::null_mut(),
+ )?);
+ Ok(Self {
+ index: Index(idx as c_int),
+ base: l0_dev,
+ default_queue: queue,
+ l0_context: ctx,
+ primary_context: primary_context,
+ properties: None,
+ image_properties: None,
+ memory_properties: None,
+ compute_properties: None,
+ })
+ }
+
+ fn get_properties<'a>(&'a mut self) -> l0::Result<&'a l0::sys::ze_device_properties_t> {
+ if let Some(ref prop) = self.properties {
+ return Ok(prop);
+ }
+ match self.base.get_properties() {
+ Ok(prop) => Ok(self.properties.get_or_insert(prop)),
+ Err(e) => Err(e),
+ }
+ }
+
+ fn get_image_properties(&mut self) -> l0::Result<&l0::sys::ze_device_image_properties_t> {
+ if let Some(ref prop) = self.image_properties {
+ return Ok(prop);
+ }
+ match self.base.get_image_properties() {
+ Ok(prop) => Ok(self.image_properties.get_or_insert(prop)),
+ Err(e) => Err(e),
+ }
+ }
+
+ fn get_memory_properties(&mut self) -> l0::Result<&[l0::sys::ze_device_memory_properties_t]> {
+ if let Some(ref prop) = self.memory_properties {
+ return Ok(prop);
+ }
+ match self.base.get_memory_properties() {
+ Ok(prop) => Ok(self.memory_properties.get_or_insert(prop)),
+ Err(e) => Err(e),
+ }
+ }
+
+ fn get_compute_properties(&mut self) -> l0::Result<&l0::sys::ze_device_compute_properties_t> {
+ if let Some(ref prop) = self.compute_properties {
+ return Ok(prop);
+ }
+ match self.base.get_compute_properties() {
+ Ok(prop) => Ok(self.compute_properties.get_or_insert(prop)),
+ Err(e) => Err(e),
+ }
+ }
+
+ pub fn late_init(&mut self) {
+ self.primary_context.as_option_mut().unwrap().device = self as *mut _;
+ }
+
+ fn get_max_simd(&mut self) -> l0::Result<u32> {
+ let props = self.get_compute_properties()?;
+ Ok(*props.subGroupSizes[0..props.numSubGroupSizes as usize]
+ .iter()
+ .max()
+ .unwrap())
+ }
+}
+
+pub fn init(driver: &l0::Driver) -> Result<Vec<Device>, CUresult> {
+ let ze_devices = driver.devices()?;
+ let mut devices = ze_devices
+ .into_iter()
+ .enumerate()
+ .map(|(idx, d)| unsafe { Device::new(driver, d, idx) })
+ .collect::<Result<Vec<_>, _>>()?;
+ for dev in devices.iter_mut() {
+ dev.late_init();
+ dev.primary_context.late_init();
+ }
+ Ok(devices)
+}
+
+pub fn get_count(count: *mut c_int) -> Result<(), CUresult> {
+ let len = GlobalState::lock(|state| state.devices.len())?;
+ unsafe { *count = len as c_int };
+ Ok(())
+}
+
+pub fn get(device: *mut Index, ordinal: c_int) -> Result<(), CUresult> {
+ if device == ptr::null_mut() || ordinal < 0 {
+ return Err(CUresult::CUDA_ERROR_INVALID_VALUE);
+ }
+ let len = GlobalState::lock(|state| state.devices.len())?;
+ if ordinal < (len as i32) {
+ unsafe { *device = Index(ordinal) };
+ Ok(())
+ } else {
+ Err(CUresult::CUDA_ERROR_INVALID_VALUE)
+ }
+}
+
+pub fn get_name(name: *mut c_char, len: i32, dev_idx: Index) -> Result<(), CUresult> {
+ if name == ptr::null_mut() || len < 0 {
+ return Err(CUresult::CUDA_ERROR_INVALID_VALUE);
+ }
+ let name_ptr = GlobalState::lock_device(dev_idx, |dev| {
+ let props = dev.get_properties()?;
+ Ok::<_, l0::sys::ze_result_t>(props.name.as_ptr())
+ })??;
+ let name_len = (0..256)
+ .position(|i| unsafe { *name_ptr.add(i) } == 0)
+ .unwrap_or(256);
+ let mut dst_null_pos = cmp::min((len - 1) as usize, name_len);
+ unsafe { std::ptr::copy_nonoverlapping(name_ptr, name, dst_null_pos) };
+ if name_len + PROJECT_URL_SUFFIX_LONG.len() < (len as usize) {
+ unsafe {
+ std::ptr::copy_nonoverlapping(
+ PROJECT_URL_SUFFIX_LONG.as_ptr(),
+ name.add(name_len) as *mut _,
+ PROJECT_URL_SUFFIX_LONG.len(),
+ )
+ };
+ dst_null_pos += PROJECT_URL_SUFFIX_LONG.len();
+ } else if name_len + PROJECT_URL_SUFFIX_SHORT.len() < (len as usize) {
+ unsafe {
+ std::ptr::copy_nonoverlapping(
+ PROJECT_URL_SUFFIX_SHORT.as_ptr(),
+ name.add(name_len) as *mut _,
+ PROJECT_URL_SUFFIX_SHORT.len(),
+ )
+ };
+ dst_null_pos += PROJECT_URL_SUFFIX_SHORT.len();
+ }
+ unsafe { *(name.add(dst_null_pos)) = 0 };
+ Ok(())
+}
+
+pub fn total_mem_v2(bytes: *mut usize, dev_idx: Index) -> Result<(), CUresult> {
+ if bytes == ptr::null_mut() {
+ return Err(CUresult::CUDA_ERROR_INVALID_VALUE);
+ }
+ let mem_props = GlobalState::lock_device(dev_idx, |dev| {
+ let mem_props = dev.get_memory_properties()?;
+ Ok::<_, l0::sys::ze_result_t>(mem_props)
+ })??;
+ let max_mem = mem_props
+ .iter()
+ .map(|p| p.totalSize)
+ .max()
+ .ok_or(CUresult::CUDA_ERROR_ILLEGAL_STATE)?;
+ unsafe { *bytes = max_mem as usize };
+ Ok(())
+}
+
+impl CUdevice_attribute {
+ fn get_static_value(self) -> Option<i32> {
+ match self {
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_GPU_OVERLAP => Some(1),
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT => Some(1),
+ // TODO: fix this for DG1
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_INTEGRATED => Some(1),
+ // TODO: go back to this once we have more funcitonality implemented
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR => Some(8),
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR => Some(0),
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY => Some(1),
+ _ => None,
+ }
+ }
+}
+
+pub fn get_attribute(
+ pi: *mut i32,
+ attrib: CUdevice_attribute,
+ dev_idx: Index,
+) -> Result<(), CUresult> {
+ if pi == ptr::null_mut() {
+ return Err(CUresult::CUDA_ERROR_INVALID_VALUE);
+ }
+ if let Some(value) = attrib.get_static_value() {
+ unsafe { *pi = value };
+ return Ok(());
+ }
+ let value = match attrib {
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_ASYNC_ENGINE_COUNT => {
+ GlobalState::lock_device(dev_idx, |dev| {
+ let props = dev.get_properties()?;
+ Ok::<_, l0::sys::ze_result_t>(props.maxHardwareContexts as i32)
+ })??
+ }
+ // Streaming Multiprocessor corresponds roughly to a sub-slice (thread group can't cross either)
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT => {
+ GlobalState::lock_device(dev_idx, |dev| {
+ let props = dev.get_properties()?;
+ Ok::<_, l0::sys::ze_result_t>((props.numSlices * props.numSubslicesPerSlice) as i32)
+ })??
+ }
+ // I honestly don't know how to answer this query
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_MULTIPROCESSOR => {
+ GlobalState::lock_device(dev_idx, |dev| {
+ let max_simd = dev.get_max_simd()?;
+ let props = dev.get_properties()?;
+ Ok::<_, l0::sys::ze_result_t>(
+ (props.numEUsPerSubslice * props.numThreadsPerEU * max_simd) as i32,
+ )
+ })??
+ }
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK => {
+ GlobalState::lock_device(dev_idx, |dev| {
+ let props = dev.get_compute_properties()?;
+ Ok::<_, l0::sys::ze_result_t>(cmp::min(
+ i32::max_value() as u32,
+ props.maxTotalGroupSize,
+ ) as i32)
+ })??
+ }
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_WIDTH => {
+ GlobalState::lock_device(dev_idx, |dev| {
+ let props = dev.get_image_properties()?;
+ Ok::<_, l0::sys::ze_result_t>(cmp::min(
+ props.maxImageDims1D,
+ c_int::max_value() as u32,
+ ) as c_int)
+ })??
+ }
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_X => {
+ GlobalState::lock_device(dev_idx, |dev| {
+ let props = dev.get_compute_properties()?;
+ Ok::<_, l0::sys::ze_result_t>(cmp::min(
+ i32::max_value() as u32,
+ props.maxGroupCountX,
+ ) as i32)
+ })??
+ }
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Y => {
+ GlobalState::lock_device(dev_idx, |dev| {
+ let props = dev.get_compute_properties()?;
+ Ok::<_, l0::sys::ze_result_t>(cmp::min(
+ i32::max_value() as u32,
+ props.maxGroupCountY,
+ ) as i32)
+ })??
+ }
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Z => {
+ GlobalState::lock_device(dev_idx, |dev| {
+ let props = dev.get_compute_properties()?;
+ Ok::<_, l0::sys::ze_result_t>(cmp::min(
+ i32::max_value() as u32,
+ props.maxGroupCountZ,
+ ) as i32)
+ })??
+ }
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_X => {
+ GlobalState::lock_device(dev_idx, |dev| {
+ let props = dev.get_compute_properties()?;
+ Ok::<_, l0::sys::ze_result_t>(
+ cmp::min(i32::max_value() as u32, props.maxGroupSizeX) as i32,
+ )
+ })??
+ }
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Y => {
+ GlobalState::lock_device(dev_idx, |dev| {
+ let props = dev.get_compute_properties()?;
+ Ok::<_, l0::sys::ze_result_t>(
+ cmp::min(i32::max_value() as u32, props.maxGroupSizeY) as i32,
+ )
+ })??
+ }
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Z => {
+ GlobalState::lock_device(dev_idx, |dev| {
+ let props = dev.get_compute_properties()?;
+ Ok::<_, l0::sys::ze_result_t>(
+ cmp::min(i32::max_value() as u32, props.maxGroupSizeZ) as i32,
+ )
+ })??
+ }
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_MAX_SHARED_MEMORY_PER_BLOCK => {
+ GlobalState::lock_device(dev_idx, |dev| {
+ let props = dev.get_compute_properties()?;
+ Ok::<_, l0::sys::ze_result_t>(props.maxSharedLocalMemory as i32)
+ })??
+ }
+ CUdevice_attribute::CU_DEVICE_ATTRIBUTE_WARP_SIZE => {
+ GlobalState::lock_device(dev_idx, |dev| Ok::<_, CUresult>(dev.get_max_simd()? as i32))??
+ }
+ _ => {
+ // TODO: support more attributes for CUDA runtime
+ /*
+ return Err(l0::Error(
+ l0::sys::ze_result_t::ZE_RESULT_ERROR_UNSUPPORTED_FEATURE,
+ ))
+ */
+ return Ok(());
+ }
+ };
+ unsafe { *pi = value };
+ Ok(())
+}
+
+pub fn get_uuid(uuid: *mut CUuuid_st, dev_idx: Index) -> Result<(), CUresult> {
+ let ze_uuid = GlobalState::lock_device(dev_idx, |dev| {
+ let props = dev.get_properties()?;
+ Ok::<_, l0::sys::ze_result_t>(props.uuid)
+ })??;
+ unsafe {
+ *uuid = CUuuid_st {
+ bytes: mem::transmute(ze_uuid.id),
+ }
+ };
+ Ok(())
+}
+
+pub fn primary_ctx_get_state(
+ dev_idx: Index,
+ flags: *mut u32,
+ active: *mut i32,
+) -> Result<(), CUresult> {
+ let (is_active, flags_value) = GlobalState::lock_device(dev_idx, |dev| {
+ // This is safe because primary context can't be dropped
+ let ctx_ptr = &mut dev.primary_context as *mut _;
+ let flags_ptr =
+ (&unsafe { dev.primary_context.as_ref_unchecked() }.flags) as *const AtomicU32;
+ let is_active = context::CONTEXT_STACK
+ .with(|stack| stack.borrow().last().map(|x| *x))
+ .map(|current| current == ctx_ptr)
+ .unwrap_or(false);
+ let flags_value = unsafe { &*flags_ptr }.load(Ordering::Relaxed);
+ Ok::<_, l0::sys::ze_result_t>((is_active, flags_value))
+ })??;
+ unsafe { *active = if is_active { 1 } else { 0 } };
+ unsafe { *flags = flags_value };
+ Ok(())
+}
+
+pub fn primary_ctx_retain(
+ pctx: *mut *mut context::Context,
+ dev_idx: Index,
+) -> Result<(), CUresult> {
+ let ctx_ptr = GlobalState::lock_device(dev_idx, |dev| &mut dev.primary_context as *mut _)?;
+ unsafe { *pctx = ctx_ptr };
+ Ok(())
+}
+
+// TODO: allow for retain/reset/release of primary context
+pub(crate) fn primary_ctx_release_v2(_dev_idx: Index) -> CUresult {
+ CUresult::CUDA_SUCCESS
+}
+
+#[cfg(test)]
+mod test {
+ use super::super::test::CudaDriverFns;
+ use super::super::CUresult;
+
+ cuda_driver_test!(primary_ctx_default_inactive);
+
+ fn primary_ctx_default_inactive<T: CudaDriverFns>() {
+ assert_eq!(T::cuInit(0), CUresult::CUDA_SUCCESS);
+ let mut flags = u32::max_value();
+ let mut active = i32::max_value();
+ assert_eq!(
+ T::cuDevicePrimaryCtxGetState(0, &mut flags, &mut active),
+ CUresult::CUDA_SUCCESS
+ );
+ assert_eq!(flags, 0);
+ assert_eq!(active, 0);
+ }
+}
diff --git a/zluda/src/impl/export_table.rs b/zluda/src/impl/export_table.rs
new file mode 100644
index 0000000..87d7f40
--- /dev/null
+++ b/zluda/src/impl/export_table.rs
@@ -0,0 +1,372 @@
+use crate::cuda::CUresult;
+use crate::{
+ cuda::{CUcontext, CUdevice, CUmodule, CUuuid},
+ cuda_impl,
+};
+
+use super::{context, context::ContextData, device, module, Decuda, Encuda, GlobalState};
+use std::mem;
+use std::os::raw::{c_uint, c_ulong, c_ushort};
+use std::{
+ ffi::{c_void, CStr},
+ ptr, slice,
+};
+
+pub fn get(table: *mut *const std::os::raw::c_void, id: *const CUuuid) -> CUresult {
+ if table == ptr::null_mut() || id == ptr::null_mut() {
+ return CUresult::CUDA_ERROR_INVALID_VALUE;
+ }
+ let id = unsafe { *id };
+ match id {
+ TOOLS_RUNTIME_CALLBACK_HOOKS_GUID => {
+ unsafe { *table = TOOLS_RUNTIME_CALLBACK_HOOKS_VTABLE.as_ptr() as *const _ };
+ CUresult::CUDA_SUCCESS
+ }
+ CUDART_INTERFACE_GUID => {
+ unsafe { *table = CUDART_INTERFACE_VTABLE.as_ptr() as *const _ };
+ CUresult::CUDA_SUCCESS
+ }
+ TOOLS_TLS_GUID => {
+ unsafe { *table = 1 as _ };
+ CUresult::CUDA_SUCCESS
+ }
+ CONTEXT_LOCAL_STORAGE_INTERFACE_V0301_GUID => {
+ unsafe { *table = CONTEXT_LOCAL_STORAGE_INTERFACE_V0301_VTABLE.as_ptr() as *const _ };
+ CUresult::CUDA_SUCCESS
+ }
+ _ => CUresult::CUDA_ERROR_NOT_SUPPORTED,
+ }
+}
+
+const TOOLS_RUNTIME_CALLBACK_HOOKS_GUID: CUuuid = CUuuid {
+ bytes: [
+ 0xa0, 0x94, 0x79, 0x8c, 0x2e, 0x74, 0x2e, 0x74, 0x93, 0xf2, 0x08, 0x00, 0x20, 0x0c, 0x0a,
+ 0x66,
+ ],
+};
+#[repr(C)]
+union VTableEntry {
+ ptr: *const (),
+ length: usize,
+}
+unsafe impl Sync for VTableEntry {}
+const TOOLS_RUNTIME_CALLBACK_HOOKS_LENGTH: usize = 7;
+static TOOLS_RUNTIME_CALLBACK_HOOKS_VTABLE: [VTableEntry; TOOLS_RUNTIME_CALLBACK_HOOKS_LENGTH] = [
+ VTableEntry {
+ length: mem::size_of::<[VTableEntry; TOOLS_RUNTIME_CALLBACK_HOOKS_LENGTH]>(),
+ },
+ VTableEntry { ptr: ptr::null() },
+ VTableEntry {
+ ptr: runtime_callback_hooks_fn1 as *const (),
+ },
+ VTableEntry { ptr: ptr::null() },
+ VTableEntry { ptr: ptr::null() },
+ VTableEntry { ptr: ptr::null() },
+ VTableEntry {
+ ptr: runtime_callback_hooks_fn5 as *const (),
+ },
+];
+static mut TOOLS_RUNTIME_CALLBACK_HOOKS_FN1_SPACE: [usize; 512] = [0; 512];
+
+unsafe extern "C" fn runtime_callback_hooks_fn1(ptr: *mut *mut usize, size: *mut usize) {
+ *ptr = TOOLS_RUNTIME_CALLBACK_HOOKS_FN1_SPACE.as_mut_ptr();
+ *size = TOOLS_RUNTIME_CALLBACK_HOOKS_FN1_SPACE.len();
+}
+
+static mut TOOLS_RUNTIME_CALLBACK_HOOKS_FN5_SPACE: [u8; 2] = [0; 2];
+
+unsafe extern "C" fn runtime_callback_hooks_fn5(ptr: *mut *mut u8, size: *mut usize) -> *mut u8 {
+ *ptr = TOOLS_RUNTIME_CALLBACK_HOOKS_FN5_SPACE.as_mut_ptr();
+ *size = TOOLS_RUNTIME_CALLBACK_HOOKS_FN5_SPACE.len();
+ return TOOLS_RUNTIME_CALLBACK_HOOKS_FN5_SPACE.as_mut_ptr();
+}
+
+const CUDART_INTERFACE_GUID: CUuuid = CUuuid {
+ bytes: [
+ 0x6b, 0xd5, 0xfb, 0x6c, 0x5b, 0xf4, 0xe7, 0x4a, 0x89, 0x87, 0xd9, 0x39, 0x12, 0xfd, 0x9d,
+ 0xf9,
+ ],
+};
+
+const CUDART_INTERFACE_LENGTH: usize = 10;
+static CUDART_INTERFACE_VTABLE: [VTableEntry; CUDART_INTERFACE_LENGTH] = [
+ VTableEntry {
+ length: mem::size_of::<[VTableEntry; CUDART_INTERFACE_LENGTH]>(),
+ },
+ VTableEntry { ptr: ptr::null() },
+ VTableEntry {
+ ptr: cudart_interface_fn1 as *const (),
+ },
+ VTableEntry { ptr: ptr::null() },
+ VTableEntry { ptr: ptr::null() },
+ VTableEntry { ptr: ptr::null() },
+ VTableEntry {
+ ptr: get_module_from_cubin as *const (),
+ },
+ VTableEntry {
+ ptr: cudart_interface_fn6 as *const (),
+ },
+ VTableEntry { ptr: ptr::null() },
+ VTableEntry { ptr: ptr::null() },
+];
+
+unsafe extern "C" fn cudart_interface_fn1(pctx: *mut CUcontext, dev: CUdevice) -> CUresult {
+ cudart_interface_fn1_impl(pctx.decuda(), dev.decuda()).encuda()
+}
+
+fn cudart_interface_fn1_impl(
+ pctx: *mut *mut context::Context,
+ dev: device::Index,
+) -> Result<(), CUresult> {
+ let ctx_ptr = GlobalState::lock_device(dev, |d| &mut d.primary_context as *mut _)?;
+ unsafe { *pctx = ctx_ptr };
+ Ok(())
+}
+
+/*
+fat_cubin:
+typedef struct {
+ int magic;
+ int version;
+ const unsigned long long* data;
+ void *filename_or_fatbins; /* version 1: offline filename,
+ * version 2: array of prelinked fatbins */
+} __fatBinC_Wrapper_t;
+
+data start with this header:
+#define FATBIN_MAGIC 0xBA55ED50U
+#define OLD_STYLE_FATBIN_MAGIC 0x1EE55A01U
+#define FATBIN_VERSION 0x0001U
+
+struct fatbinary_ALIGN_(8) fatBinaryHeader
+{
+ unsigned int magic; // FATBIN_MAGIC
+ unsigned short version; // FATBIN_VERSION
+ unsigned short headerSize;
+ unsigned long long int fatSize; // size of the entire fat binary excluding this header
+};
+
+there's binary data after header
+
+*/
+
+const FATBINC_MAGIC: c_uint = 0x466243B1;
+const FATBINC_VERSION: c_uint = 0x1;
+
+#[repr(C)]
+struct FatbincWrapper {
+ magic: c_uint,
+ version: c_uint,
+ data: *const FatbinHeader,
+ filename_or_fatbins: *const c_void,
+}
+
+const FATBIN_MAGIC: c_uint = 0xBA55ED50;
+const FATBIN_VERSION: c_ushort = 0x01;
+
+#[repr(C, align(8))]
+struct FatbinHeader {
+ magic: c_uint,
+ version: c_ushort,
+ header_size: c_ushort,
+ files_size: c_ulong, // excluding frame header, size of all blocks framed by this frame
+}
+
+const FATBIN_FILE_HEADER_KIND_PTX: c_ushort = 0x01;
+const FATBIN_FILE_HEADER_VERSION_CURRENT: c_ushort = 0x101;
+
+// assembly file header is a bit different, but we don't care
+#[repr(C)]
+struct FatbinFileHeader {
+ kind: c_ushort,
+ version: c_ushort,
+ header_size: c_uint,
+ padded_payload_size: c_uint,
+ unknown0: c_uint, // check if it's written into separately
+ payload_size: c_uint,
+ unknown1: c_uint,
+ unknown2: c_uint,
+ sm_version: c_uint,
+ bit_width: c_uint,
+ unknown3: c_uint,
+ unknown4: c_ulong,
+ unknown5: c_ulong,
+ uncompressed_payload: c_ulong,
+}
+
+unsafe extern "C" fn get_module_from_cubin(
+ result: *mut CUmodule,
+ fatbinc_wrapper: *const FatbincWrapper,
+ ptr1: *mut c_void,
+ ptr2: *mut c_void,
+) -> CUresult {
+ // Not sure what those two parameters are actually used for,
+ // they are somehow involved in __cudaRegisterHostVar
+ if ptr1 != ptr::null_mut() || ptr2 != ptr::null_mut() {
+ return CUresult::CUDA_ERROR_NOT_SUPPORTED;
+ }
+ if result == ptr::null_mut()
+ || (*fatbinc_wrapper).magic != FATBINC_MAGIC
+ || (*fatbinc_wrapper).version != FATBINC_VERSION
+ {
+ return CUresult::CUDA_ERROR_INVALID_VALUE;
+ }
+ let result = result.decuda();
+ let fatbin_header = (*fatbinc_wrapper).data;
+ if (*fatbin_header).magic != FATBIN_MAGIC || (*fatbin_header).version != FATBIN_VERSION {
+ return CUresult::CUDA_ERROR_INVALID_VALUE;
+ }
+ let file = (fatbin_header as *const u8).add((*fatbin_header).header_size as usize);
+ let end = file.add((*fatbin_header).files_size as usize);
+ let mut ptx_files = get_ptx_files(file, end);
+ ptx_files.sort_unstable_by_key(|f| c_uint::max_value() - (**f).sm_version);
+ for file in ptx_files {
+ let slice = slice::from_raw_parts(
+ (file as *const u8).add((*file).header_size as usize),
+ (*file).payload_size as usize,
+ );
+ let kernel_text =
+ lz4::block::decompress(slice, Some((*file).uncompressed_payload as i32)).unwrap();
+ let kernel_text_string = match CStr::from_bytes_with_nul(&kernel_text) {
+ Ok(c_str) => match c_str.to_str() {
+ Ok(s) => s,
+ Err(_) => continue,
+ },
+ Err(_) => continue,
+ };
+ let module = module::SpirvModule::new(kernel_text_string);
+ match module {
+ Ok(module) => {
+ match module::load_data_impl(result, module) {
+ Ok(()) => {}
+ Err(err) => return err,
+ }
+ return CUresult::CUDA_SUCCESS;
+ }
+ Err(_) => continue,
+ }
+ }
+ CUresult::CUDA_ERROR_COMPAT_NOT_SUPPORTED_ON_DEVICE
+}
+
+unsafe fn get_ptx_files(file: *const u8, end: *const u8) -> Vec<*const FatbinFileHeader> {
+ let mut index = file;
+ let mut result = Vec::new();
+ while index < end {
+ let file = index as *const FatbinFileHeader;
+ if (*file).kind == FATBIN_FILE_HEADER_KIND_PTX
+ && (*file).version == FATBIN_FILE_HEADER_VERSION_CURRENT
+ {
+ result.push(file)
+ }
+ index = index.add((*file).header_size as usize + (*file).padded_payload_size as usize);
+ }
+ result
+}
+
+unsafe extern "C" fn cudart_interface_fn6(_: u64) {}
+
+const TOOLS_TLS_GUID: CUuuid = CUuuid {
+ bytes: [
+ 0x42, 0xd8, 0x5a, 0x81, 0x23, 0xf6, 0xcb, 0x47, 0x82, 0x98, 0xf6, 0xe7, 0x8a, 0x3a, 0xec,
+ 0xdc,
+ ],
+};
+
+const CONTEXT_LOCAL_STORAGE_INTERFACE_V0301_GUID: CUuuid = CUuuid {
+ bytes: [
+ 0xc6, 0x93, 0x33, 0x6e, 0x11, 0x21, 0xdf, 0x11, 0xa8, 0xc3, 0x68, 0xf3, 0x55, 0xd8, 0x95,
+ 0x93,
+ ],
+};
+
+// the table is much bigger and starts earlier
+static CONTEXT_LOCAL_STORAGE_INTERFACE_V0301_VTABLE: [VTableEntry; 4] = [
+ VTableEntry {
+ ptr: context_local_storage_ctor as *const (),
+ },
+ VTableEntry {
+ ptr: context_local_storage_dtor as *const (),
+ },
+ VTableEntry {
+ ptr: context_local_storage_get_state as *const (),
+ },
+ VTableEntry { ptr: ptr::null() },
+];
+
+// some kind of ctor
+unsafe extern "C" fn context_local_storage_ctor(
+ cu_ctx: CUcontext, // always zero
+ mgr: *mut cuda_impl::rt::ContextStateManager,
+ ctx_state: *mut cuda_impl::rt::ContextState,
+ // clsContextDestroyCallback, have to be called on cuDevicePrimaryCtxReset
+ dtor_cb: Option<
+ extern "C" fn(
+ CUcontext,
+ *mut cuda_impl::rt::ContextStateManager,
+ *mut cuda_impl::rt::ContextState,
+ ),
+ >,
+) -> CUresult {
+ context_local_storage_ctor_impl(cu_ctx.decuda(), mgr, ctx_state, dtor_cb).encuda()
+}
+
+fn context_local_storage_ctor_impl(
+ cu_ctx: *mut context::Context,
+ mgr: *mut cuda_impl::rt::ContextStateManager,
+ ctx_state: *mut cuda_impl::rt::ContextState,
+ dtor_cb: Option<
+ extern "C" fn(
+ CUcontext,
+ *mut cuda_impl::rt::ContextStateManager,
+ *mut cuda_impl::rt::ContextState,
+ ),
+ >,
+) -> Result<(), CUresult> {
+ lock_context(cu_ctx, |ctx: &mut ContextData| {
+ ctx.cuda_manager = mgr;
+ ctx.cuda_state = ctx_state;
+ ctx.cuda_dtor_cb = dtor_cb;
+ })
+}
+
+// some kind of dtor
+unsafe extern "C" fn context_local_storage_dtor(_: *mut usize, _: *mut ()) -> u32 {
+ 0
+}
+
+unsafe extern "C" fn context_local_storage_get_state(
+ ctx_state: *mut *mut cuda_impl::rt::ContextState,
+ cu_ctx: CUcontext,
+ state_mgr: *mut cuda_impl::rt::ContextStateManager,
+) -> CUresult {
+ context_local_storage_get_state_impl(ctx_state, cu_ctx.decuda(), state_mgr).encuda()
+}
+
+fn context_local_storage_get_state_impl(
+ ctx_state: *mut *mut cuda_impl::rt::ContextState,
+ cu_ctx: *mut context::Context,
+ _: *mut cuda_impl::rt::ContextStateManager,
+) -> Result<(), CUresult> {
+ let cuda_state = lock_context(cu_ctx, |ctx: &mut ContextData| ctx.cuda_state)?;
+ if cuda_state == ptr::null_mut() {
+ Err(CUresult::CUDA_ERROR_INVALID_VALUE)
+ } else {
+ unsafe { *ctx_state = cuda_state };
+ Ok(())
+ }
+}
+
+fn lock_context<T>(
+ cu_ctx: *mut context::Context,
+ fn_impl: impl FnOnce(&mut ContextData) -> T,
+) -> Result<T, CUresult> {
+ if cu_ctx == ptr::null_mut() {
+ GlobalState::lock_current_context(fn_impl)
+ } else {
+ GlobalState::lock(|_| {
+ let ctx = unsafe { &mut *cu_ctx }.as_result_mut()?;
+ Ok(fn_impl(ctx))
+ })?
+ }
+}
diff --git a/zluda/src/impl/function.rs b/zluda/src/impl/function.rs
new file mode 100644
index 0000000..27bf9b6
--- /dev/null
+++ b/zluda/src/impl/function.rs
@@ -0,0 +1,112 @@
+use ::std::os::raw::{c_uint, c_void};
+use std::{hint, ptr};
+
+use crate::cuda::CUfunction_attribute;
+
+use super::{stream::Stream, CUresult, GlobalState, HasLivenessCookie, LiveCheck};
+
+pub type Function = LiveCheck<FunctionData>;
+
+impl HasLivenessCookie for FunctionData {
+ #[cfg(target_pointer_width = "64")]
+ const COOKIE: usize = 0x5e2ab14d5840678e;
+
+ #[cfg(target_pointer_width = "32")]
+ const COOKIE: usize = 0x33e6a1e6;
+
+ const LIVENESS_FAIL: CUresult = CUresult::CUDA_ERROR_INVALID_HANDLE;
+
+ fn try_drop(&mut self) -> Result<(), CUresult> {
+ Ok(())
+ }
+}
+
+pub struct FunctionData {
+ pub base: l0::Kernel<'static>,
+ pub arg_size: Vec<usize>,
+ pub use_shared_mem: bool,
+ pub properties: Option<Box<l0::sys::ze_kernel_properties_t>>,
+}
+
+impl FunctionData {
+ fn get_properties(&mut self) -> Result<&l0::sys::ze_kernel_properties_t, l0::sys::ze_result_t> {
+ if let None = self.properties {
+ self.properties = Some(self.base.get_properties()?)
+ }
+ match self.properties {
+ Some(ref props) => Ok(props.as_ref()),
+ None => unsafe { hint::unreachable_unchecked() },
+ }
+ }
+}
+
+pub fn launch_kernel(
+ f: *mut Function,
+ grid_dim_x: c_uint,
+ grid_dim_y: c_uint,
+ grid_dim_z: c_uint,
+ block_dim_x: c_uint,
+ block_dim_y: c_uint,
+ block_dim_z: c_uint,
+ shared_mem_bytes: c_uint,
+ hstream: *mut Stream,
+ kernel_params: *mut *mut c_void,
+ extra: *mut *mut c_void,
+) -> Result<(), CUresult> {
+ if f == ptr::null_mut() {
+ return Err(CUresult::CUDA_ERROR_INVALID_VALUE);
+ }
+ if extra != ptr::null_mut() {
+ return Err(CUresult::CUDA_ERROR_NOT_SUPPORTED);
+ }
+ GlobalState::lock_stream(hstream, |stream| {
+ let func: &mut FunctionData = unsafe { &mut *f }.as_result_mut()?;
+ for (i, arg_size) in func.arg_size.iter().enumerate() {
+ unsafe {
+ func.base
+ .set_arg_raw(i as u32, *arg_size, *kernel_params.add(i))?
+ };
+ }
+ if func.use_shared_mem {
+ unsafe {
+ func.base.set_arg_raw(
+ func.arg_size.len() as u32,
+ shared_mem_bytes as usize,
+ ptr::null(),
+ )?
+ };
+ }
+ func.base
+ .set_group_size(block_dim_x, block_dim_y, block_dim_z)?;
+ let mut cmd_list = stream.command_list()?;
+ cmd_list.append_launch_kernel(
+ &mut func.base,
+ &[grid_dim_x, grid_dim_y, grid_dim_z],
+ None,
+ &mut [],
+ )?;
+ stream.queue.execute(cmd_list)?;
+ Ok(())
+ })?
+}
+
+pub(crate) fn get_attribute(
+ pi: *mut i32,
+ attrib: CUfunction_attribute,
+ func: *mut Function,
+) -> Result<(), CUresult> {
+ if pi == ptr::null_mut() || func == ptr::null_mut() {
+ return Err(CUresult::CUDA_ERROR_INVALID_VALUE);
+ }
+ match attrib {
+ CUfunction_attribute::CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK => {
+ let max_threads = GlobalState::lock_function(func, |func| {
+ let props = func.get_properties()?;
+ Ok::<_, CUresult>(props.maxSubgroupSize * props.maxNumSubgroups)
+ })??;
+ unsafe { *pi = max_threads as i32 };
+ Ok(())
+ }
+ _ => Err(CUresult::CUDA_ERROR_NOT_SUPPORTED),
+ }
+}
diff --git a/zluda/src/impl/memory.rs b/zluda/src/impl/memory.rs
new file mode 100644
index 0000000..f33a08c
--- /dev/null
+++ b/zluda/src/impl/memory.rs
@@ -0,0 +1,100 @@
+use super::{stream, CUresult, GlobalState};
+use std::{ffi::c_void, mem};
+
+pub fn alloc_v2(dptr: *mut *mut c_void, bytesize: usize) -> Result<(), CUresult> {
+ let ptr = GlobalState::lock_current_context(|ctx| {
+ let dev = unsafe { &mut *ctx.device };
+ Ok::<_, CUresult>(unsafe { dev.base.mem_alloc_device(&mut dev.l0_context, bytesize, 0) }?)
+ })??;
+ unsafe { *dptr = ptr };
+ Ok(())
+}
+
+pub fn copy_v2(dst: *mut c_void, src: *const c_void, bytesize: usize) -> Result<(), CUresult> {
+ GlobalState::lock_stream(stream::CU_STREAM_LEGACY, |stream| {
+ let mut cmd_list = stream.command_list()?;
+ unsafe { cmd_list.append_memory_copy_unsafe(dst, src, bytesize, None, &mut []) }?;
+ stream.queue.execute(cmd_list)?;
+ Ok::<_, CUresult>(())
+ })?
+}
+
+pub fn free_v2(ptr: *mut c_void) -> Result<(), CUresult> {
+ GlobalState::lock_current_context(|ctx| {
+ let dev = unsafe { &mut *ctx.device };
+ Ok::<_, CUresult>(unsafe { dev.l0_context.mem_free(ptr) }?)
+ })
+ .map_err(|_| CUresult::CUDA_ERROR_INVALID_VALUE)?
+}
+
+pub(crate) fn set_d32_v2(dst: *mut c_void, ui: u32, n: usize) -> Result<(), CUresult> {
+ GlobalState::lock_stream(stream::CU_STREAM_LEGACY, |stream| {
+ let mut cmd_list = stream.command_list()?;
+ unsafe {
+ cmd_list.append_memory_fill_unsafe(dst, &ui, mem::size_of::<u32>() * n, None, &mut [])
+ }?;
+ stream.queue.execute(cmd_list)?;
+ Ok::<_, CUresult>(())
+ })?
+}
+
+pub(crate) fn set_d8_v2(dst: *mut c_void, uc: u8, n: usize) -> Result<(), CUresult> {
+ GlobalState::lock_stream(stream::CU_STREAM_LEGACY, |stream| {
+ let mut cmd_list = stream.command_list()?;
+ unsafe {
+ cmd_list.append_memory_fill_unsafe(dst, &uc, mem::size_of::<u8>() * n, None, &mut [])
+ }?;
+ stream.queue.execute(cmd_list)?;
+ Ok::<_, CUresult>(())
+ })?
+}
+
+#[cfg(test)]
+mod test {
+ use super::super::test::CudaDriverFns;
+ use super::super::CUresult;
+ use std::ptr;
+
+ cuda_driver_test!(alloc_without_ctx);
+
+ fn alloc_without_ctx<T: CudaDriverFns>() {
+ assert_eq!(T::cuInit(0), CUresult::CUDA_SUCCESS);
+ let mut mem = ptr::null_mut();
+ assert_eq!(
+ T::cuMemAlloc_v2(&mut mem, std::mem::size_of::<usize>()),
+ CUresult::CUDA_ERROR_INVALID_CONTEXT
+ );
+ assert_eq!(mem, ptr::null_mut());
+ }
+
+ cuda_driver_test!(alloc_with_ctx);
+
+ fn alloc_with_ctx<T: CudaDriverFns>() {
+ assert_eq!(T::cuInit(0), CUresult::CUDA_SUCCESS);
+ let mut ctx = ptr::null_mut();
+ assert_eq!(T::cuCtxCreate_v2(&mut ctx, 0, 0), CUresult::CUDA_SUCCESS);
+ let mut mem = ptr::null_mut();
+ assert_eq!(
+ T::cuMemAlloc_v2(&mut mem, std::mem::size_of::<usize>()),
+ CUresult::CUDA_SUCCESS
+ );
+ assert_ne!(mem, ptr::null_mut());
+ assert_eq!(T::cuCtxDestroy_v2(ctx), CUresult::CUDA_SUCCESS);
+ }
+
+ cuda_driver_test!(free_without_ctx);
+
+ fn free_without_ctx<T: CudaDriverFns>() {
+ assert_eq!(T::cuInit(0), CUresult::CUDA_SUCCESS);
+ let mut ctx = ptr::null_mut();
+ assert_eq!(T::cuCtxCreate_v2(&mut ctx, 0, 0), CUresult::CUDA_SUCCESS);
+ let mut mem = ptr::null_mut();
+ assert_eq!(
+ T::cuMemAlloc_v2(&mut mem, std::mem::size_of::<usize>()),
+ CUresult::CUDA_SUCCESS
+ );
+ assert_ne!(mem, ptr::null_mut());
+ assert_eq!(T::cuCtxDestroy_v2(ctx), CUresult::CUDA_SUCCESS);
+ assert_eq!(T::cuMemFree_v2(mem), CUresult::CUDA_ERROR_INVALID_VALUE);
+ }
+}
diff --git a/zluda/src/impl/mod.rs b/zluda/src/impl/mod.rs
new file mode 100644
index 0000000..086d260
--- /dev/null
+++ b/zluda/src/impl/mod.rs
@@ -0,0 +1,351 @@
+use crate::{
+ cuda::{CUctx_st, CUdevice, CUdeviceptr, CUfunc_st, CUmod_st, CUresult, CUstream_st},
+ r#impl::device::Device,
+};
+use std::{
+ ffi::c_void,
+ mem::{self, ManuallyDrop},
+ os::raw::c_int,
+ ptr,
+ sync::Mutex,
+ sync::TryLockError,
+};
+
+#[cfg(test)]
+#[macro_use]
+pub mod test;
+pub mod context;
+pub mod device;
+pub mod export_table;
+pub mod function;
+pub mod memory;
+pub mod module;
+pub mod stream;
+
+#[cfg(debug_assertions)]
+pub fn unimplemented() -> CUresult {
+ unimplemented!()
+}
+
+#[cfg(not(debug_assertions))]
+pub fn unimplemented() -> CUresult {
+ CUresult::CUDA_ERROR_NOT_SUPPORTED
+}
+
+pub trait HasLivenessCookie: Sized {
+ const COOKIE: usize;
+ const LIVENESS_FAIL: CUresult;
+
+ fn try_drop(&mut self) -> Result<(), CUresult>;
+}
+
+// This struct is a best-effort check if wrapped value has been dropped,
+// while it's inherently safe, its use coming from FFI is very unsafe
+#[repr(C)]
+pub struct LiveCheck<T: HasLivenessCookie> {
+ cookie: usize,
+ data: ManuallyDrop<T>,
+}
+
+impl<T: HasLivenessCookie> LiveCheck<T> {
+ pub fn new(data: T) -> Self {
+ LiveCheck {
+ cookie: T::COOKIE,
+ data: ManuallyDrop::new(data),
+ }
+ }
+
+ fn destroy_impl(this: *mut Self) -> Result<(), CUresult> {
+ let mut ctx_box = ManuallyDrop::new(unsafe { Box::from_raw(this) });
+ ctx_box.try_drop()?;
+ unsafe { ManuallyDrop::drop(&mut ctx_box) };
+ Ok(())
+ }
+
+ unsafe fn ptr_from_inner(this: *mut T) -> *mut Self {
+ let outer_ptr = (this as *mut u8).sub(mem::size_of::<usize>());
+ outer_ptr as *mut Self
+ }
+
+ pub unsafe fn as_ref_unchecked(&self) -> &T {
+ &self.data
+ }
+
+ pub fn as_option_mut(&mut self) -> Option<&mut T> {
+ if self.cookie == T::COOKIE {
+ Some(&mut self.data)
+ } else {
+ None
+ }
+ }
+
+ pub fn as_result(&self) -> Result<&T, CUresult> {
+ if self.cookie == T::COOKIE {
+ Ok(&self.data)
+ } else {
+ Err(T::LIVENESS_FAIL)
+ }
+ }
+
+ pub fn as_result_mut(&mut self) -> Result<&mut T, CUresult> {
+ if self.cookie == T::COOKIE {
+ Ok(&mut self.data)
+ } else {
+ Err(T::LIVENESS_FAIL)
+ }
+ }
+
+ #[must_use]
+ pub fn try_drop(&mut self) -> Result<(), CUresult> {
+ if self.cookie == T::COOKIE {
+ self.cookie = 0;
+ self.data.try_drop()?;
+ unsafe { ManuallyDrop::drop(&mut self.data) };
+ return Ok(());
+ }
+ Err(T::LIVENESS_FAIL)
+ }
+}
+
+impl<T: HasLivenessCookie> Drop for LiveCheck<T> {
+ fn drop(&mut self) {
+ self.cookie = 0;
+ }
+}
+
+pub trait CudaRepr: Sized {
+ type Impl: Sized;
+}
+
+impl<T: CudaRepr> CudaRepr for *mut T {
+ type Impl = *mut T::Impl;
+}
+
+pub trait Decuda<To> {
+ fn decuda(self: Self) -> To;
+}
+
+impl<T: CudaRepr> Decuda<*mut T::Impl> for *mut T {
+ fn decuda(self: Self) -> *mut T::Impl {
+ self as *mut _
+ }
+}
+
+impl From<l0::sys::ze_result_t> for CUresult {
+ fn from(result: l0::sys::ze_result_t) -> Self {
+ match result {
+ l0::sys::ze_result_t::ZE_RESULT_SUCCESS => CUresult::CUDA_SUCCESS,
+ l0_sys::ze_result_t::ZE_RESULT_ERROR_UNINITIALIZED => {
+ CUresult::CUDA_ERROR_NOT_INITIALIZED
+ }
+ l0_sys::ze_result_t::ZE_RESULT_ERROR_INVALID_ENUMERATION => {
+ CUresult::CUDA_ERROR_INVALID_VALUE
+ }
+ l0_sys::ze_result_t::ZE_RESULT_ERROR_INVALID_ARGUMENT => {
+ CUresult::CUDA_ERROR_INVALID_VALUE
+ }
+ l0_sys::ze_result_t::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY => {
+ CUresult::CUDA_ERROR_OUT_OF_MEMORY
+ }
+ l0_sys::ze_result_t::ZE_RESULT_ERROR_UNSUPPORTED_FEATURE => {
+ CUresult::CUDA_ERROR_NOT_SUPPORTED
+ }
+ _ => CUresult::CUDA_ERROR_UNKNOWN,
+ }
+ }
+}
+
+impl<T> From<TryLockError<T>> for CUresult {
+ fn from(_: TryLockError<T>) -> Self {
+ CUresult::CUDA_ERROR_ILLEGAL_STATE
+ }
+}
+
+pub trait Encuda {
+ type To: Sized;
+ fn encuda(self: Self) -> Self::To;
+}
+
+impl Encuda for CUresult {
+ type To = CUresult;
+ fn encuda(self: Self) -> Self::To {
+ self
+ }
+}
+
+impl Encuda for l0::sys::ze_result_t {
+ type To = CUresult;
+ fn encuda(self: Self) -> Self::To {
+ self.into()
+ }
+}
+
+impl Encuda for () {
+ type To = CUresult;
+ fn encuda(self: Self) -> Self::To {
+ CUresult::CUDA_SUCCESS
+ }
+}
+
+impl<T1: Encuda<To = CUresult>, T2: Encuda<To = CUresult>> Encuda for Result<T1, T2> {
+ type To = CUresult;
+ fn encuda(self: Self) -> Self::To {
+ match self {
+ Ok(e) => e.encuda(),
+ Err(e) => e.encuda(),
+ }
+ }
+}
+
+lazy_static! {
+ static ref GLOBAL_STATE: Mutex<Option<GlobalState>> = Mutex::new(None);
+}
+
+struct GlobalState {
+ devices: Vec<Device>,
+}
+
+unsafe impl Send for GlobalState {}
+
+impl GlobalState {
+ fn lock<T>(f: impl FnOnce(&mut GlobalState) -> T) -> Result<T, CUresult> {
+ let mut mutex = GLOBAL_STATE
+ .lock()
+ .unwrap_or_else(|poison| poison.into_inner());
+ let global_state = mutex.as_mut().ok_or(CUresult::CUDA_ERROR_ILLEGAL_STATE)?;
+ Ok(f(global_state))
+ }
+
+ fn lock_device<T>(
+ device::Index(dev_idx): device::Index,
+ f: impl FnOnce(&'static mut device::Device) -> T,
+ ) -> Result<T, CUresult> {
+ if dev_idx < 0 {
+ return Err(CUresult::CUDA_ERROR_INVALID_DEVICE);
+ }
+ Self::lock(|global_state| {
+ if dev_idx >= global_state.devices.len() as c_int {
+ Err(CUresult::CUDA_ERROR_INVALID_DEVICE)
+ } else {
+ Ok(f(unsafe {
+ transmute_lifetime_mut(&mut global_state.devices[dev_idx as usize])
+ }))
+ }
+ })?
+ }
+
+ fn lock_current_context<F: FnOnce(&mut context::ContextData) -> R, R>(
+ f: F,
+ ) -> Result<R, CUresult> {
+ Self::lock_current_context_unchecked(|ctx| Ok(f(ctx.as_result_mut()?)))?
+ }
+
+ fn lock_current_context_unchecked<F: FnOnce(&mut context::Context) -> R, R>(
+ f: F,
+ ) -> Result<R, CUresult> {
+ context::CONTEXT_STACK.with(|stack| {
+ stack
+ .borrow_mut()
+ .last_mut()
+ .ok_or(CUresult::CUDA_ERROR_INVALID_CONTEXT)
+ .map(|ctx| GlobalState::lock(|_| f(unsafe { &mut **ctx })))?
+ })
+ }
+
+ fn lock_stream<T>(
+ stream: *mut stream::Stream,
+ f: impl FnOnce(&mut stream::StreamData) -> T,
+ ) -> Result<T, CUresult> {
+ if stream == ptr::null_mut()
+ || stream == stream::CU_STREAM_LEGACY
+ || stream == stream::CU_STREAM_PER_THREAD
+ {
+ Self::lock_current_context(|ctx| Ok(f(&mut ctx.default_stream)))?
+ } else {
+ Self::lock(|_| {
+ let stream = unsafe { &mut *stream }.as_result_mut()?;
+ Ok(f(stream))
+ })?
+ }
+ }
+
+ fn lock_function<T>(
+ func: *mut function::Function,
+ f: impl FnOnce(&mut function::FunctionData) -> T,
+ ) -> Result<T, CUresult> {
+ if func == ptr::null_mut() {
+ return Err(CUresult::CUDA_ERROR_INVALID_HANDLE);
+ }
+ Self::lock(|_| {
+ let func = unsafe { &mut *func }.as_result_mut()?;
+ Ok(f(func))
+ })?
+ }
+}
+
+// TODO: implement
+fn is_intel_gpu_driver(_: &l0::Driver) -> bool {
+ true
+}
+
+pub fn init() -> Result<(), CUresult> {
+ let mut global_state = GLOBAL_STATE
+ .lock()
+ .map_err(|_| CUresult::CUDA_ERROR_UNKNOWN)?;
+ if global_state.is_some() {
+ return Ok(());
+ }
+ l0::init()?;
+ let drivers = l0::Driver::get()?;
+ let devices = match drivers.into_iter().find(is_intel_gpu_driver) {
+ None => return Err(CUresult::CUDA_ERROR_UNKNOWN),
+ Some(driver) => device::init(&driver)?,
+ };
+ *global_state = Some(GlobalState { devices });
+ drop(global_state);
+ Ok(())
+}
+
+unsafe fn transmute_lifetime_mut<'a, 'b, T: ?Sized>(t: &'a mut T) -> &'b mut T {
+ mem::transmute(t)
+}
+
+pub fn driver_get_version() -> c_int {
+ i32::max_value()
+}
+
+impl<'a> CudaRepr for CUctx_st {
+ type Impl = context::Context;
+}
+
+impl<'a> CudaRepr for CUdevice {
+ type Impl = device::Index;
+}
+
+impl Decuda<device::Index> for CUdevice {
+ fn decuda(self) -> device::Index {
+ device::Index(self.0)
+ }
+}
+
+impl<'a> CudaRepr for CUdeviceptr {
+ type Impl = *mut c_void;
+}
+
+impl Decuda<*mut c_void> for CUdeviceptr {
+ fn decuda(self) -> *mut c_void {
+ self.0 as *mut _
+ }
+}
+
+impl<'a> CudaRepr for CUmod_st {
+ type Impl = module::Module;
+}
+
+impl<'a> CudaRepr for CUfunc_st {
+ type Impl = function::Function;
+}
+
+impl<'a> CudaRepr for CUstream_st {
+ type Impl = stream::Stream;
+}
diff --git a/zluda/src/impl/module.rs b/zluda/src/impl/module.rs
new file mode 100644
index 0000000..cba030e
--- /dev/null
+++ b/zluda/src/impl/module.rs
@@ -0,0 +1,188 @@
+use std::{
+ collections::hash_map, collections::HashMap, ffi::c_void, ffi::CStr, ffi::CString, mem,
+ os::raw::c_char, ptr, slice,
+};
+
+use super::{
+ device, function::Function, function::FunctionData, CUresult, GlobalState, HasLivenessCookie,
+ LiveCheck,
+};
+use ptx;
+
+pub type Module = LiveCheck<ModuleData>;
+
+impl HasLivenessCookie for ModuleData {
+ #[cfg(target_pointer_width = "64")]
+ const COOKIE: usize = 0xf1313bd46505f98a;
+
+ #[cfg(target_pointer_width = "32")]
+ const COOKIE: usize = 0xbdbe3f15;
+
+ const LIVENESS_FAIL: CUresult = CUresult::CUDA_ERROR_INVALID_HANDLE;
+
+ fn try_drop(&mut self) -> Result<(), CUresult> {
+ Ok(())
+ }
+}
+
+pub struct ModuleData {
+ pub spirv: SpirvModule,
+ // This should be a Vec<>, but I'm feeling lazy
+ pub device_binaries: HashMap<device::Index, CompiledModule>,
+}
+
+pub struct SpirvModule {
+ pub binaries: Vec<u32>,
+ pub kernel_info: HashMap<String, ptx::KernelInfo>,
+ pub should_link_ptx_impl: Option<&'static [u8]>,
+ pub build_options: CString,
+}
+
+pub struct CompiledModule {
+ pub base: l0::Module,
+ pub kernels: HashMap<CString, Box<Function>>,
+}
+
+impl<L, T, E> From<ptx::ParseError<L, T, E>> for CUresult {
+ fn from(_: ptx::ParseError<L, T, E>) -> Self {
+ CUresult::CUDA_ERROR_INVALID_PTX
+ }
+}
+
+impl From<ptx::TranslateError> for CUresult {
+ fn from(_: ptx::TranslateError) -> Self {
+ CUresult::CUDA_ERROR_INVALID_PTX
+ }
+}
+
+impl SpirvModule {
+ pub fn new_raw<'a>(text: *const c_char) -> Result<Self, CUresult> {
+ let u8_text = unsafe { CStr::from_ptr(text) };
+ let ptx_text = u8_text
+ .to_str()
+ .map_err(|_| CUresult::CUDA_ERROR_INVALID_PTX)?;
+ Self::new(ptx_text)
+ }
+
+ pub fn new<'a>(ptx_text: &str) -> Result<Self, CUresult> {
+ let mut errors = Vec::new();
+ let ast = ptx::ModuleParser::new().parse(&mut errors, ptx_text)?;
+ let spirv_module = ptx::to_spirv_module(ast)?;
+ Ok(SpirvModule {
+ binaries: spirv_module.assemble(),
+ kernel_info: spirv_module.kernel_info,
+ should_link_ptx_impl: spirv_module.should_link_ptx_impl,
+ build_options: spirv_module.build_options,
+ })
+ }
+
+ pub fn compile(&self, ctx: &mut l0::Context, dev: &l0::Device) -> Result<l0::Module, CUresult> {
+ let byte_il = unsafe {
+ slice::from_raw_parts(
+ self.binaries.as_ptr() as *const u8,
+ self.binaries.len() * mem::size_of::<u32>(),
+ )
+ };
+ let l0_module = match self.should_link_ptx_impl {
+ None => {
+ l0::Module::build_spirv(ctx, dev, byte_il, Some(self.build_options.as_c_str())).0
+ }
+ Some(ptx_impl) => {
+ l0::Module::build_link_spirv(
+ ctx,
+ &dev,
+ &[ptx_impl, byte_il],
+ Some(self.build_options.as_c_str()),
+ )
+ .0
+ }
+ };
+ Ok(l0_module?)
+ }
+}
+
+pub fn get_function(
+ hfunc: *mut *mut Function,
+ hmod: *mut Module,
+ name: *const c_char,
+) -> Result<(), CUresult> {
+ if hfunc == ptr::null_mut() || hmod == ptr::null_mut() || name == ptr::null() {
+ return Err(CUresult::CUDA_ERROR_INVALID_VALUE);
+ }
+ let name = unsafe { CStr::from_ptr(name) }.to_owned();
+ let function: *mut Function = GlobalState::lock_current_context(|ctx| {
+ let module = unsafe { &mut *hmod }.as_result_mut()?;
+ let device = unsafe { &mut *ctx.device };
+ let compiled_module = match module.device_binaries.entry(device.index) {
+ hash_map::Entry::Occupied(entry) => entry.into_mut(),
+ hash_map::Entry::Vacant(entry) => {
+ let new_module = CompiledModule {
+ base: module.spirv.compile(&mut device.l0_context, &device.base)?,
+ kernels: HashMap::new(),
+ };
+ entry.insert(new_module)
+ }
+ };
+ let kernel = match compiled_module.kernels.entry(name) {
+ hash_map::Entry::Occupied(entry) => entry.into_mut().as_mut(),
+ hash_map::Entry::Vacant(entry) => {
+ let kernel_info = module
+ .spirv
+ .kernel_info
+ .get(unsafe {
+ std::str::from_utf8_unchecked(entry.key().as_c_str().to_bytes())
+ })
+ .ok_or(CUresult::CUDA_ERROR_NOT_FOUND)?;
+ let mut kernel =
+ l0::Kernel::new_resident(&compiled_module.base, entry.key().as_c_str())?;
+ kernel.set_indirect_access(
+ l0::sys::ze_kernel_indirect_access_flags_t::ZE_KERNEL_INDIRECT_ACCESS_FLAG_DEVICE
+ | l0::sys::ze_kernel_indirect_access_flags_t::ZE_KERNEL_INDIRECT_ACCESS_FLAG_HOST
+ | l0::sys::ze_kernel_indirect_access_flags_t::ZE_KERNEL_INDIRECT_ACCESS_FLAG_SHARED
+ )?;
+ entry.insert(Box::new(Function::new(FunctionData {
+ base: kernel,
+ arg_size: kernel_info.arguments_sizes.clone(),
+ use_shared_mem: kernel_info.uses_shared_mem,
+ properties: None,
+ })))
+ }
+ };
+ Ok::<_, CUresult>(kernel as *mut _)
+ })??;
+ unsafe { *hfunc = function };
+ Ok(())
+}
+
+pub(crate) fn load_data(pmod: *mut *mut Module, image: *const c_void) -> Result<(), CUresult> {
+ let spirv_data = SpirvModule::new_raw(image as *const _)?;
+ load_data_impl(pmod, spirv_data)
+}
+
+pub fn load_data_impl(pmod: *mut *mut Module, spirv_data: SpirvModule) -> Result<(), CUresult> {
+ let module = GlobalState::lock_current_context(|ctx| {
+ let device = unsafe { &mut *ctx.device };
+ let l0_module = spirv_data.compile(&mut device.l0_context, &device.base)?;
+ let mut device_binaries = HashMap::new();
+ let compiled_module = CompiledModule {
+ base: l0_module,
+ kernels: HashMap::new(),
+ };
+ device_binaries.insert(device.index, compiled_module);
+ let module_data = ModuleData {
+ spirv: spirv_data,
+ device_binaries,
+ };
+ Ok::<_, CUresult>(module_data)
+ })??;
+ let module_ptr = Box::into_raw(Box::new(Module::new(module)));
+ unsafe { *pmod = module_ptr };
+ Ok(())
+}
+
+pub(crate) fn unload(module: *mut Module) -> Result<(), CUresult> {
+ if module == ptr::null_mut() {
+ return Err(CUresult::CUDA_ERROR_INVALID_VALUE);
+ }
+ GlobalState::lock(|_| Module::destroy_impl(module))?
+}
diff --git a/zluda/src/impl/stream.rs b/zluda/src/impl/stream.rs
new file mode 100644
index 0000000..e212dfc
--- /dev/null
+++ b/zluda/src/impl/stream.rs
@@ -0,0 +1,242 @@
+use super::{
+ context::{Context, ContextData},
+ CUresult, GlobalState,
+};
+use std::{mem, ptr};
+
+use super::{HasLivenessCookie, LiveCheck};
+
+pub type Stream = LiveCheck<StreamData>;
+
+pub const CU_STREAM_LEGACY: *mut Stream = 1 as *mut _;
+pub const CU_STREAM_PER_THREAD: *mut Stream = 2 as *mut _;
+
+impl HasLivenessCookie for StreamData {
+ #[cfg(target_pointer_width = "64")]
+ const COOKIE: usize = 0x512097354de18d35;
+
+ #[cfg(target_pointer_width = "32")]
+ const COOKIE: usize = 0x77d5cc0b;
+
+ const LIVENESS_FAIL: CUresult = CUresult::CUDA_ERROR_INVALID_HANDLE;
+
+ fn try_drop(&mut self) -> Result<(), CUresult> {
+ if self.context != ptr::null_mut() {
+ let context = unsafe { &mut *self.context };
+ if !context.streams.remove(&(self as *mut _)) {
+ return Err(CUresult::CUDA_ERROR_UNKNOWN);
+ }
+ }
+ Ok(())
+ }
+}
+
+pub struct StreamData {
+ pub context: *mut ContextData,
+ pub queue: l0::CommandQueue,
+}
+
+impl StreamData {
+ pub fn new_unitialized(ctx: &mut l0::Context, dev: &l0::Device) -> Result<Self, CUresult> {
+ Ok(StreamData {
+ context: ptr::null_mut(),
+ queue: l0::CommandQueue::new(ctx, dev)?,
+ })
+ }
+ pub fn new(ctx: &mut ContextData) -> Result<Self, CUresult> {
+ let l0_ctx = &mut unsafe { &mut *ctx.device }.l0_context;
+ let l0_dev = &unsafe { &*ctx.device }.base;
+ Ok(StreamData {
+ context: ctx as *mut _,
+ queue: l0::CommandQueue::new(l0_ctx, l0_dev)?,
+ })
+ }
+
+ pub fn command_list(&self) -> Result<l0::CommandList, l0::sys::_ze_result_t> {
+ let ctx = unsafe { &mut *self.context };
+ let dev = unsafe { &mut *ctx.device };
+ l0::CommandList::new(&mut dev.l0_context, &dev.base)
+ }
+}
+
+impl Drop for StreamData {
+ fn drop(&mut self) {
+ if self.context == ptr::null_mut() {
+ return;
+ }
+ unsafe { (&mut *self.context).streams.remove(&(&mut *self as *mut _)) };
+ }
+}
+
+pub(crate) fn get_ctx(hstream: *mut Stream, pctx: *mut *mut Context) -> Result<(), CUresult> {
+ if pctx == ptr::null_mut() {
+ return Err(CUresult::CUDA_ERROR_INVALID_VALUE);
+ }
+ let ctx_ptr = GlobalState::lock_stream(hstream, |stream| stream.context)?;
+ if ctx_ptr == ptr::null_mut() {
+ return Err(CUresult::CUDA_ERROR_CONTEXT_IS_DESTROYED);
+ }
+ unsafe { *pctx = Context::ptr_from_inner(ctx_ptr) };
+ Ok(())
+}
+
+pub(crate) fn create(phstream: *mut *mut Stream, _flags: u32) -> Result<(), CUresult> {
+ let stream_ptr = GlobalState::lock_current_context(|ctx| {
+ let mut stream_box = Box::new(Stream::new(StreamData::new(ctx)?));
+ let stream_ptr = stream_box.as_mut().as_option_mut().unwrap() as *mut _;
+ if !ctx.streams.insert(stream_ptr) {
+ return Err(CUresult::CUDA_ERROR_UNKNOWN);
+ }
+ mem::forget(stream_box);
+ Ok::<_, CUresult>(stream_ptr)
+ })??;
+ unsafe { *phstream = Stream::ptr_from_inner(stream_ptr) };
+ Ok(())
+}
+
+pub(crate) fn destroy_v2(pstream: *mut Stream) -> Result<(), CUresult> {
+ if pstream == ptr::null_mut() || pstream == CU_STREAM_LEGACY || pstream == CU_STREAM_PER_THREAD
+ {
+ return Err(CUresult::CUDA_ERROR_INVALID_VALUE);
+ }
+ GlobalState::lock(|_| Stream::destroy_impl(pstream))?
+}
+
+#[cfg(test)]
+mod test {
+ use crate::cuda::CUstream;
+
+ use super::super::test::CudaDriverFns;
+ use super::super::CUresult;
+ use std::{ptr, thread};
+
+ const CU_STREAM_LEGACY: CUstream = 1 as *mut _;
+ const CU_STREAM_PER_THREAD: CUstream = 2 as *mut _;
+
+ cuda_driver_test!(default_stream_uses_current_ctx_legacy);
+ cuda_driver_test!(default_stream_uses_current_ctx_ptsd);
+
+ fn default_stream_uses_current_ctx_legacy<T: CudaDriverFns>() {
+ default_stream_uses_current_ctx_impl::<T>(CU_STREAM_LEGACY);
+ }
+
+ fn default_stream_uses_current_ctx_ptsd<T: CudaDriverFns>() {
+ default_stream_uses_current_ctx_impl::<T>(CU_STREAM_PER_THREAD);
+ }
+
+ fn default_stream_uses_current_ctx_impl<T: CudaDriverFns>(stream: CUstream) {
+ assert_eq!(T::cuInit(0), CUresult::CUDA_SUCCESS);
+ let mut ctx1 = ptr::null_mut();
+ assert_eq!(T::cuCtxCreate_v2(&mut ctx1, 0, 0), CUresult::CUDA_SUCCESS);
+ let mut stream_ctx1 = ptr::null_mut();
+ assert_eq!(
+ T::cuStreamGetCtx(stream, &mut stream_ctx1),
+ CUresult::CUDA_SUCCESS
+ );
+ assert_eq!(ctx1, stream_ctx1);
+ let mut ctx2 = ptr::null_mut();
+ assert_eq!(T::cuCtxCreate_v2(&mut ctx2, 0, 0), CUresult::CUDA_SUCCESS);
+ assert_ne!(ctx1, ctx2);
+ let mut stream_ctx2 = ptr::null_mut();
+ assert_eq!(
+ T::cuStreamGetCtx(stream, &mut stream_ctx2),
+ CUresult::CUDA_SUCCESS
+ );
+ assert_eq!(ctx2, stream_ctx2);
+ // Cleanup
+ assert_eq!(T::cuCtxDestroy_v2(ctx1), CUresult::CUDA_SUCCESS);
+ assert_eq!(T::cuCtxDestroy_v2(ctx2), CUresult::CUDA_SUCCESS);
+ }
+
+ cuda_driver_test!(stream_context_destroyed);
+
+ fn stream_context_destroyed<T: CudaDriverFns>() {
+ assert_eq!(T::cuInit(0), CUresult::CUDA_SUCCESS);
+ let mut ctx = ptr::null_mut();
+ assert_eq!(T::cuCtxCreate_v2(&mut ctx, 0, 0), CUresult::CUDA_SUCCESS);
+ let mut stream = ptr::null_mut();
+ assert_eq!(T::cuStreamCreate(&mut stream, 0), CUresult::CUDA_SUCCESS);
+ let mut stream_ctx1 = ptr::null_mut();
+ assert_eq!(
+ T::cuStreamGetCtx(stream, &mut stream_ctx1),
+ CUresult::CUDA_SUCCESS
+ );
+ assert_eq!(stream_ctx1, ctx);
+ assert_eq!(T::cuCtxDestroy_v2(ctx), CUresult::CUDA_SUCCESS);
+ let mut stream_ctx2 = ptr::null_mut();
+ // When a context gets destroyed, its streams are also destroyed
+ let cuda_result = T::cuStreamGetCtx(stream, &mut stream_ctx2);
+ assert!(
+ cuda_result == CUresult::CUDA_ERROR_INVALID_HANDLE
+ || cuda_result == CUresult::CUDA_ERROR_INVALID_CONTEXT
+ || cuda_result == CUresult::CUDA_ERROR_CONTEXT_IS_DESTROYED
+ );
+ assert_eq!(
+ T::cuStreamDestroy_v2(stream),
+ CUresult::CUDA_ERROR_INVALID_HANDLE
+ );
+ // Check if creating another context is possible
+ let mut ctx2 = ptr::null_mut();
+ assert_eq!(T::cuCtxCreate_v2(&mut ctx2, 0, 0), CUresult::CUDA_SUCCESS);
+ // Cleanup
+ assert_eq!(T::cuCtxDestroy_v2(ctx2), CUresult::CUDA_SUCCESS);
+ }
+
+ cuda_driver_test!(stream_moves_context_to_another_thread);
+
+ fn stream_moves_context_to_another_thread<T: CudaDriverFns>() {
+ assert_eq!(T::cuInit(0), CUresult::CUDA_SUCCESS);
+ let mut ctx = ptr::null_mut();
+ assert_eq!(T::cuCtxCreate_v2(&mut ctx, 0, 0), CUresult::CUDA_SUCCESS);
+ let mut stream = ptr::null_mut();
+ assert_eq!(T::cuStreamCreate(&mut stream, 0), CUresult::CUDA_SUCCESS);
+ let mut stream_ctx1 = ptr::null_mut();
+ assert_eq!(
+ T::cuStreamGetCtx(stream, &mut stream_ctx1),
+ CUresult::CUDA_SUCCESS
+ );
+ assert_eq!(stream_ctx1, ctx);
+ let stream_ptr = stream as usize;
+ let stream_ctx_on_thread = thread::spawn(move || {
+ let mut stream_ctx2 = ptr::null_mut();
+ assert_eq!(
+ T::cuStreamGetCtx(stream_ptr as *mut _, &mut stream_ctx2),
+ CUresult::CUDA_SUCCESS
+ );
+ stream_ctx2 as usize
+ })
+ .join()
+ .unwrap();
+ assert_eq!(stream_ctx1, stream_ctx_on_thread as *mut _);
+ // Cleanup
+ assert_eq!(T::cuStreamDestroy_v2(stream), CUresult::CUDA_SUCCESS);
+ assert_eq!(T::cuCtxDestroy_v2(ctx), CUresult::CUDA_SUCCESS);
+ }
+
+ cuda_driver_test!(can_destroy_stream);
+
+ fn can_destroy_stream<T: CudaDriverFns>() {
+ assert_eq!(T::cuInit(0), CUresult::CUDA_SUCCESS);
+ let mut ctx = ptr::null_mut();
+ assert_eq!(T::cuCtxCreate_v2(&mut ctx, 0, 0), CUresult::CUDA_SUCCESS);
+ let mut stream = ptr::null_mut();
+ assert_eq!(T::cuStreamCreate(&mut stream, 0), CUresult::CUDA_SUCCESS);
+ assert_eq!(T::cuStreamDestroy_v2(stream), CUresult::CUDA_SUCCESS);
+ // Cleanup
+ assert_eq!(T::cuCtxDestroy_v2(ctx), CUresult::CUDA_SUCCESS);
+ }
+
+ cuda_driver_test!(cant_destroy_default_stream);
+
+ fn cant_destroy_default_stream<T: CudaDriverFns>() {
+ assert_eq!(T::cuInit(0), CUresult::CUDA_SUCCESS);
+ let mut ctx = ptr::null_mut();
+ assert_eq!(T::cuCtxCreate_v2(&mut ctx, 0, 0), CUresult::CUDA_SUCCESS);
+ assert_ne!(
+ T::cuStreamDestroy_v2(super::CU_STREAM_LEGACY as *mut _),
+ CUresult::CUDA_SUCCESS
+ );
+ // Cleanup
+ assert_eq!(T::cuCtxDestroy_v2(ctx), CUresult::CUDA_SUCCESS);
+ }
+}
diff --git a/zluda/src/impl/test.rs b/zluda/src/impl/test.rs
new file mode 100644
index 0000000..b36ccd8
--- /dev/null
+++ b/zluda/src/impl/test.rs
@@ -0,0 +1,157 @@
+#![allow(non_snake_case)]
+
+use crate::cuda as zluda;
+use crate::cuda::CUstream;
+use crate::cuda::CUuuid;
+use crate::{
+ cuda::{CUdevice, CUdeviceptr},
+ r#impl::CUresult,
+};
+use ::std::{
+ ffi::c_void,
+ os::raw::{c_int, c_uint},
+};
+use cuda_driver_sys as cuda;
+
+#[macro_export]
+macro_rules! cuda_driver_test {
+ ($func:ident) => {
+ paste! {
+ #[test]
+ fn [<$func _zluda>]() {
+ $func::<crate::r#impl::test::Zluda>()
+ }
+
+ #[test]
+ fn [<$func _cuda>]() {
+ $func::<crate::r#impl::test::Cuda>()
+ }
+ }
+ };
+}
+
+pub trait CudaDriverFns {
+ fn cuInit(flags: c_uint) -> CUresult;
+ fn cuCtxCreate_v2(pctx: *mut *mut c_void, flags: c_uint, dev: c_int) -> CUresult;
+ fn cuCtxDestroy_v2(ctx: *mut c_void) -> CUresult;
+ fn cuCtxPopCurrent_v2(pctx: *mut *mut c_void) -> CUresult;
+ fn cuCtxGetApiVersion(ctx: *mut c_void, version: *mut c_uint) -> CUresult;
+ fn cuCtxGetCurrent(pctx: *mut *mut c_void) -> CUresult;
+ fn cuMemAlloc_v2(dptr: *mut *mut c_void, bytesize: usize) -> CUresult;
+ fn cuDeviceGetUuid(uuid: *mut CUuuid, dev: c_int) -> CUresult;
+ fn cuDevicePrimaryCtxGetState(dev: c_int, flags: *mut c_uint, active: *mut c_int) -> CUresult;
+ fn cuStreamGetCtx(hStream: CUstream, pctx: *mut *mut c_void) -> CUresult;
+ fn cuStreamCreate(stream: *mut CUstream, flags: c_uint) -> CUresult;
+ fn cuMemFree_v2(mem: *mut c_void) -> CUresult;
+ fn cuStreamDestroy_v2(stream: CUstream) -> CUresult;
+}
+
+pub struct Zluda();
+
+impl CudaDriverFns for Zluda {
+ fn cuInit(_flags: c_uint) -> CUresult {
+ zluda::cuInit(_flags as _)
+ }
+
+ fn cuCtxCreate_v2(pctx: *mut *mut c_void, flags: c_uint, dev: c_int) -> CUresult {
+ zluda::cuCtxCreate_v2(pctx as *mut _, flags, CUdevice(dev))
+ }
+
+ fn cuCtxDestroy_v2(ctx: *mut c_void) -> CUresult {
+ zluda::cuCtxDestroy_v2(ctx as *mut _)
+ }
+
+ fn cuCtxPopCurrent_v2(pctx: *mut *mut c_void) -> CUresult {
+ zluda::cuCtxPopCurrent_v2(pctx as *mut _)
+ }
+
+ fn cuCtxGetApiVersion(ctx: *mut c_void, version: *mut c_uint) -> CUresult {
+ zluda::cuCtxGetApiVersion(ctx as *mut _, version)
+ }
+
+ fn cuCtxGetCurrent(pctx: *mut *mut c_void) -> CUresult {
+ zluda::cuCtxGetCurrent(pctx as *mut _)
+ }
+ fn cuMemAlloc_v2(dptr: *mut *mut c_void, bytesize: usize) -> CUresult {
+ zluda::cuMemAlloc_v2(dptr as *mut _, bytesize)
+ }
+
+ fn cuDeviceGetUuid(uuid: *mut CUuuid, dev: c_int) -> CUresult {
+ zluda::cuDeviceGetUuid(uuid, CUdevice(dev))
+ }
+
+ fn cuDevicePrimaryCtxGetState(dev: c_int, flags: *mut c_uint, active: *mut c_int) -> CUresult {
+ zluda::cuDevicePrimaryCtxGetState(CUdevice(dev), flags, active)
+ }
+
+ fn cuStreamGetCtx(hStream: CUstream, pctx: *mut *mut c_void) -> CUresult {
+ zluda::cuStreamGetCtx(hStream, pctx as _)
+ }
+
+ fn cuStreamCreate(stream: *mut CUstream, flags: c_uint) -> CUresult {
+ zluda::cuStreamCreate(stream, flags)
+ }
+
+ fn cuMemFree_v2(dptr: *mut c_void) -> CUresult {
+ zluda::cuMemFree_v2(CUdeviceptr(dptr as _))
+ }
+
+ fn cuStreamDestroy_v2(stream: CUstream) -> CUresult {
+ zluda::cuStreamDestroy_v2(stream)
+ }
+}
+
+pub struct Cuda();
+
+impl CudaDriverFns for Cuda {
+ fn cuInit(flags: c_uint) -> CUresult {
+ unsafe { CUresult(cuda::cuInit(flags) as c_uint) }
+ }
+
+ fn cuCtxCreate_v2(pctx: *mut *mut c_void, flags: c_uint, dev: c_int) -> CUresult {
+ unsafe { CUresult(cuda::cuCtxCreate_v2(pctx as *mut _, flags, dev) as c_uint) }
+ }
+
+ fn cuCtxDestroy_v2(ctx: *mut c_void) -> CUresult {
+ unsafe { CUresult(cuda::cuCtxDestroy_v2(ctx as *mut _) as c_uint) }
+ }
+
+ fn cuCtxPopCurrent_v2(pctx: *mut *mut c_void) -> CUresult {
+ unsafe { CUresult(cuda::cuCtxPopCurrent_v2(pctx as *mut _) as c_uint) }
+ }
+
+ fn cuCtxGetApiVersion(ctx: *mut c_void, version: *mut c_uint) -> CUresult {
+ unsafe { CUresult(cuda::cuCtxGetApiVersion(ctx as *mut _, version) as c_uint) }
+ }
+
+ fn cuCtxGetCurrent(pctx: *mut *mut c_void) -> CUresult {
+ unsafe { CUresult(cuda::cuCtxGetCurrent(pctx as *mut _) as c_uint) }
+ }
+ fn cuMemAlloc_v2(dptr: *mut *mut c_void, bytesize: usize) -> CUresult {
+ unsafe { CUresult(cuda::cuMemAlloc_v2(dptr as *mut _, bytesize) as c_uint) }
+ }
+
+ fn cuDeviceGetUuid(uuid: *mut CUuuid, dev: c_int) -> CUresult {
+ unsafe { CUresult(cuda::cuDeviceGetUuid(uuid as *mut _, dev) as c_uint) }
+ }
+
+ fn cuDevicePrimaryCtxGetState(dev: c_int, flags: *mut c_uint, active: *mut c_int) -> CUresult {
+ unsafe { CUresult(cuda::cuDevicePrimaryCtxGetState(dev, flags, active) as c_uint) }
+ }
+
+ fn cuStreamGetCtx(hStream: CUstream, pctx: *mut *mut c_void) -> CUresult {
+ unsafe { CUresult(cuda::cuStreamGetCtx(hStream as _, pctx as _) as c_uint) }
+ }
+
+ fn cuStreamCreate(stream: *mut CUstream, flags: c_uint) -> CUresult {
+ unsafe { CUresult(cuda::cuStreamCreate(stream as _, flags as _) as c_uint) }
+ }
+
+ fn cuMemFree_v2(mem: *mut c_void) -> CUresult {
+ unsafe { CUresult(cuda::cuMemFree_v2(mem as _) as c_uint) }
+ }
+
+ fn cuStreamDestroy_v2(stream: CUstream) -> CUresult {
+ unsafe { CUresult(cuda::cuStreamDestroy_v2(stream as _) as c_uint) }
+ }
+}
diff --git a/zluda/src/lib.rs b/zluda/src/lib.rs
new file mode 100644
index 0000000..0f7d014
--- /dev/null
+++ b/zluda/src/lib.rs
@@ -0,0 +1,16 @@
+extern crate level_zero as l0;
+extern crate level_zero_sys as l0_sys;
+#[macro_use]
+extern crate lazy_static;
+#[cfg(test)]
+extern crate cuda_driver_sys;
+extern crate lz4;
+#[cfg(test)]
+#[macro_use]
+extern crate paste;
+extern crate ptx;
+
+#[allow(warnings)]
+mod cuda;
+mod cuda_impl;
+pub(crate) mod r#impl;
diff --git a/zluda_inject/Cargo.toml b/zluda_inject/Cargo.toml
new file mode 100644
index 0000000..5dbb14b
--- /dev/null
+++ b/zluda_inject/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "zluda_inject"
+version = "0.0.0"
+authors = ["Andrzej Janik <[email protected]>"]
+edition = "2018"
+
+[[bin]]
+name = "zluda"
+path = "src/main.rs"
+
+[target.'cfg(windows)'.dependencies]
+zluda_redirect = { path = "../zluda_redirect" }
+winapi = { version = "0.3", features = ["processthreadsapi", "std", "synchapi"] }
+detours-sys = "0.1"
+clap = "2.33"
+guid = "0.1" \ No newline at end of file
diff --git a/zluda_inject/src/bin.rs b/zluda_inject/src/bin.rs
new file mode 100644
index 0000000..e021a41
--- /dev/null
+++ b/zluda_inject/src/bin.rs
@@ -0,0 +1,106 @@
+extern crate clap;
+#[macro_use]
+extern crate guid;
+extern crate detours_sys;
+extern crate winapi;
+
+use std::error::Error;
+use std::ffi::OsStr;
+use std::mem;
+use std::os::windows::ffi::OsStrExt;
+use std::ptr;
+
+use winapi::um::processthreadsapi::{GetExitCodeProcess, ResumeThread};
+use winapi::um::synchapi::WaitForSingleObject;
+use winapi::um::winbase::{INFINITE, WAIT_FAILED};
+
+use clap::{App, AppSettings, Arg};
+
+#[macro_use]
+mod win;
+
+fn main() -> Result<(), Box<dyn Error>> {
+ let matches = App::new("ZLUDA injector")
+ .setting(AppSettings::TrailingVarArg)
+ .arg(
+ Arg::with_name("EXE")
+ .help("Path to the executable to be injected with ZLUDA")
+ .required(true),
+ )
+ .arg(
+ Arg::with_name("ARGS")
+ .multiple(true)
+ .help("Arguments that will be passed to <EXE>"),
+ )
+ .get_matches();
+ let exe = matches.value_of_os("EXE").unwrap();
+ let args: Vec<&OsStr> = matches
+ .values_of_os("ARGS")
+ .map(|x| x.collect())
+ .unwrap_or_else(|| Vec::new());
+ let mut cmd_line = Vec::<u16>::with_capacity(exe.len() + 2);
+ cmd_line.push('\"' as u16);
+ copy_to(exe, &mut cmd_line);
+ cmd_line.push('\"' as u16);
+ cmd_line.push(' ' as u16);
+ args.split_last().map(|(last_arg, args)| {
+ for arg in args {
+ cmd_line.reserve(arg.len());
+ copy_to(arg, &mut cmd_line);
+ cmd_line.push(' ' as u16);
+ }
+ copy_to(last_arg, &mut cmd_line);
+ });
+
+ cmd_line.push(0);
+ let mut startup_info = unsafe { mem::zeroed::<detours_sys::_STARTUPINFOW>() };
+ let mut proc_info = unsafe { mem::zeroed::<detours_sys::_PROCESS_INFORMATION>() };
+ os_call!(
+ detours_sys::DetourCreateProcessWithDllExW(
+ ptr::null(),
+ cmd_line.as_mut_ptr(),
+ ptr::null_mut(),
+ ptr::null_mut(),
+ 0,
+ 0,
+ ptr::null_mut(),
+ ptr::null(),
+ &mut startup_info as *mut _,
+ &mut proc_info as *mut _,
+ "zluda_redirect.dll\0".as_ptr() as *const i8,
+ Option::None
+ ),
+ |x| x != 0
+ );
+ let mut exe_path = std::env::current_dir()?
+ .as_os_str()
+ .encode_wide()
+ .collect::<Vec<_>>();
+ let guid = guid! {"C225FC0C-00D7-40B8-935A-7E342A9344C1"};
+ os_call!(
+ detours_sys::DetourCopyPayloadToProcess(
+ proc_info.hProcess,
+ mem::transmute(&guid),
+ exe_path.as_mut_ptr() as *mut _,
+ (exe_path.len() * mem::size_of::<u16>()) as u32
+ ),
+ |x| x != 0
+ );
+ os_call!(ResumeThread(proc_info.hThread), |x| x as i32 != -1);
+ os_call!(WaitForSingleObject(proc_info.hProcess, INFINITE), |x| x
+ != WAIT_FAILED);
+ let mut child_exit_code: u32 = 0;
+ os_call!(
+ GetExitCodeProcess(proc_info.hProcess, &mut child_exit_code as *mut _),
+ |x| x != 0
+ );
+ std::process::exit(child_exit_code as i32)
+}
+
+fn copy_to(from: &OsStr, to: &mut Vec<u16>) {
+ for x in from.encode_wide() {
+ to.push(x);
+ }
+}
+
+//
diff --git a/zluda_inject/src/main.rs b/zluda_inject/src/main.rs
new file mode 100644
index 0000000..6e292f2
--- /dev/null
+++ b/zluda_inject/src/main.rs
@@ -0,0 +1,5 @@
+#[cfg(target_os = "windows")]
+mod bin;
+
+#[cfg(not(target_os = "windows"))]
+fn main() {} \ No newline at end of file
diff --git a/zluda_inject/src/win.rs b/zluda_inject/src/win.rs
new file mode 100644
index 0000000..ec57ffb
--- /dev/null
+++ b/zluda_inject/src/win.rs
@@ -0,0 +1,148 @@
+#![allow(non_snake_case)]
+
+use std::error;
+use std::fmt;
+use std::ptr;
+
+mod c {
+ use std::ffi::c_void;
+ use std::os::raw::c_ulong;
+
+ pub type DWORD = c_ulong;
+ pub type HANDLE = LPVOID;
+ pub type LPVOID = *mut c_void;
+ pub type HINSTANCE = HANDLE;
+ pub type HMODULE = HINSTANCE;
+ pub type WCHAR = u16;
+ pub type LPCWSTR = *const WCHAR;
+ pub type LPWSTR = *mut WCHAR;
+
+ pub const FACILITY_NT_BIT: DWORD = 0x1000_0000;
+ pub const FORMAT_MESSAGE_FROM_HMODULE: DWORD = 0x00000800;
+ pub const FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
+ pub const FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
+
+ extern "system" {
+ pub fn GetLastError() -> DWORD;
+ pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
+ pub fn FormatMessageW(
+ flags: DWORD,
+ lpSrc: LPVOID,
+ msgId: DWORD,
+ langId: DWORD,
+ buf: LPWSTR,
+ nsize: DWORD,
+ args: *const c_void,
+ ) -> DWORD;
+ }
+}
+
+macro_rules! last_ident {
+ ($i:ident) => {
+ stringify!($i)
+ };
+ ($start:ident, $($cont:ident),+) => {
+ last_ident!($($cont),+)
+ };
+}
+
+macro_rules! os_call {
+ ($($path:ident)::+ ($($args:expr),*), $success:expr) => {
+ let result = unsafe{ $($path)::+ ($($args),+) };
+ if !($success)(result) {
+ let name = last_ident!($($path),+);
+ let err_code = $crate::win::errno();
+ Err($crate::win::OsError{
+ function: name,
+ error_code: err_code as u32,
+ message: $crate::win::error_string(err_code)
+ })?;
+ }
+ };
+}
+
+#[derive(Debug)]
+pub struct OsError {
+ pub function: &'static str,
+ pub error_code: u32,
+ pub message: String,
+}
+
+impl fmt::Display for OsError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{:?}", self)
+ }
+}
+
+impl error::Error for OsError {
+ fn source(&self) -> Option<&(dyn error::Error + 'static)> {
+ None
+ }
+}
+
+pub fn errno() -> i32 {
+ unsafe { c::GetLastError() as i32 }
+}
+
+/// Gets a detailed string description for the given error number.
+pub fn error_string(mut errnum: i32) -> String {
+ // This value is calculated from the macro
+ // MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
+ let langId = 0x0800 as c::DWORD;
+
+ let mut buf = [0 as c::WCHAR; 2048];
+
+ unsafe {
+ let mut module = ptr::null_mut();
+ let mut flags = 0;
+
+ // NTSTATUS errors may be encoded as HRESULT, which may returned from
+ // GetLastError. For more information about Windows error codes, see
+ // `[MS-ERREF]`: https://msdn.microsoft.com/en-us/library/cc231198.aspx
+ if (errnum & c::FACILITY_NT_BIT as i32) != 0 {
+ // format according to https://support.microsoft.com/en-us/help/259693
+ const NTDLL_DLL: &[u16] = &[
+ 'N' as _, 'T' as _, 'D' as _, 'L' as _, 'L' as _, '.' as _, 'D' as _, 'L' as _,
+ 'L' as _, 0,
+ ];
+ module = c::GetModuleHandleW(NTDLL_DLL.as_ptr());
+
+ if module != ptr::null_mut() {
+ errnum ^= c::FACILITY_NT_BIT as i32;
+ flags = c::FORMAT_MESSAGE_FROM_HMODULE;
+ }
+ }
+
+ let res = c::FormatMessageW(
+ flags | c::FORMAT_MESSAGE_FROM_SYSTEM | c::FORMAT_MESSAGE_IGNORE_INSERTS,
+ module,
+ errnum as c::DWORD,
+ langId,
+ buf.as_mut_ptr(),
+ buf.len() as c::DWORD,
+ ptr::null(),
+ ) as usize;
+ if res == 0 {
+ // Sometimes FormatMessageW can fail e.g., system doesn't like langId,
+ let fm_err = errno();
+ return format!(
+ "OS Error {} (FormatMessageW() returned error {})",
+ errnum, fm_err
+ );
+ }
+
+ match String::from_utf16(&buf[..res]) {
+ Ok(mut msg) => {
+ // Trim trailing CRLF inserted by FormatMessageW
+ let len = msg.trim_end().len();
+ msg.truncate(len);
+ msg
+ }
+ Err(..) => format!(
+ "OS Error {} (FormatMessageW() returned \
+ invalid UTF-16)",
+ errnum
+ ),
+ }
+ }
+}
diff --git a/zluda_redirect/Cargo.toml b/zluda_redirect/Cargo.toml
new file mode 100644
index 0000000..46069bc
--- /dev/null
+++ b/zluda_redirect/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "zluda_redirect"
+version = "0.0.0"
+authors = ["Andrzej Janik <[email protected]>"]
+edition = "2018"
+
+[lib]
+crate-type = ["cdylib"]
+
+[target.'cfg(windows)'.dependencies]
+detours-sys = "0.1"
+wchar = "0.6"
+guid = "0.1"
+winapi = { version = "0.3", features = ["processthreadsapi", "winbase", "winnt", "winerror", "libloaderapi", "std"] } \ No newline at end of file
diff --git a/zluda_redirect/src/lib.rs b/zluda_redirect/src/lib.rs
new file mode 100644
index 0000000..c6cd4be
--- /dev/null
+++ b/zluda_redirect/src/lib.rs
@@ -0,0 +1,105 @@
+#![cfg(windows)]
+
+extern crate detours_sys;
+#[macro_use]
+extern crate guid;
+extern crate winapi;
+
+use std::mem;
+
+use detours_sys::{
+ DetourAttach, DetourDetach, DetourRestoreAfterWith, DetourTransactionBegin,
+ DetourTransactionCommit, DetourUpdateThread,
+};
+use wchar::{wch, wch_c};
+use winapi::shared::minwindef::{DWORD, FALSE, HMODULE, TRUE};
+use winapi::um::libloaderapi::LoadLibraryExW;
+use winapi::um::processthreadsapi::GetCurrentThread;
+use winapi::um::winbase::lstrcmpiW;
+use winapi::um::winnt::{DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH, HANDLE, LPCWSTR};
+
+const NVCUDA_PATH: &[u16] = wch_c!(r"C:\WINDOWS\system32\nvcuda.dll");
+const ZLUDA_DLL: &[u16] = wch!(r"nvcuda.dll");
+static mut ZLUDA_PATH: Option<Vec<u16>> = None;
+
+static mut LOAD_LIBRARY_EX: unsafe extern "system" fn(
+ lpLibFileName: LPCWSTR,
+ hFile: HANDLE,
+ dwFlags: DWORD,
+) -> HMODULE = LoadLibraryExW;
+
+#[allow(non_snake_case)]
+#[no_mangle]
+unsafe extern "system" fn ZludaLoadLibraryExW(
+ lpLibFileName: LPCWSTR,
+ hFile: HANDLE,
+ dwFlags: DWORD,
+) -> HMODULE {
+ let nvcuda_file_name = if lstrcmpiW(lpLibFileName, NVCUDA_PATH.as_ptr()) == 0 {
+ ZLUDA_PATH.as_ref().unwrap().as_ptr()
+ } else {
+ lpLibFileName
+ };
+ (LOAD_LIBRARY_EX)(nvcuda_file_name, hFile, dwFlags)
+}
+
+#[allow(non_snake_case)]
+#[no_mangle]
+unsafe extern "system" fn DllMain(_: *const u8, dwReason: u32, _: *const u8) -> i32 {
+ if dwReason == DLL_PROCESS_ATTACH {
+ DetourRestoreAfterWith();
+ match get_zluda_dll_path() {
+ Some((path, len)) => set_zluda_dll_path(path, len),
+ None => return FALSE,
+ }
+ DetourTransactionBegin();
+ DetourUpdateThread(GetCurrentThread());
+ DetourAttach(
+ std::mem::transmute(&mut LOAD_LIBRARY_EX),
+ ZludaLoadLibraryExW as *mut _,
+ );
+ DetourTransactionCommit();
+ } else if dwReason == DLL_PROCESS_DETACH {
+ DetourTransactionBegin();
+ DetourUpdateThread(GetCurrentThread());
+ DetourDetach(
+ std::mem::transmute(&mut LOAD_LIBRARY_EX),
+ ZludaLoadLibraryExW as *mut _,
+ );
+ DetourTransactionCommit();
+ }
+ TRUE
+}
+
+fn get_zluda_dll_path() -> Option<(*const u16, usize)> {
+ let guid = guid! {"C225FC0C-00D7-40B8-935A-7E342A9344C1"};
+ let mut module = std::ptr::null_mut();
+ loop {
+ module = unsafe { detours_sys::DetourEnumerateModules(module) };
+ if module == std::ptr::null_mut() {
+ break;
+ }
+ let mut size = 0;
+ let payload = unsafe {
+ detours_sys::DetourFindPayload(module, std::mem::transmute(&guid), &mut size)
+ };
+ if payload != std::ptr::null_mut() {
+ return Some((payload as *const _, (size as usize) / mem::size_of::<u16>()));
+ }
+ }
+ None
+}
+
+unsafe fn set_zluda_dll_path(path: *const u16, len: usize) {
+ let len = len as usize;
+ let mut result = Vec::<u16>::with_capacity(len + ZLUDA_DLL.len() + 2);
+ for i in 0..len {
+ result.push(*path.add(i));
+ }
+ result.push(0x5c); // \
+ for c in ZLUDA_DLL.iter().copied() {
+ result.push(c);
+ }
+ result.push(0);
+ ZLUDA_PATH = Some(result);
+}